package com.dragon.mmochat.service;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_10_5C;
import com.dragon.mmochat.message.Mmochat_1_7S;
import com.dragon.mmochat.message.Mmochat_3_10C;
import com.dragon.mmochat.message.Mmochat_3_14C;
import com.dragon.mmochat.message.Mmochat_3_15C;
import com.dragon.mmochat.message.Mmochat_3_1S;
import com.dragon.mmochat.message.Mmochat_3_2C;
import com.dragon.mmochat.message.Mmochat_3_3S;
import com.dragon.mmochat.message.Mmochat_3_4S;
import com.dragon.mmochat.message.Mmochat_3_5C;
import com.dragon.mmochat.message.Mmochat_3_5S;
import com.dragon.mmochat.message.Mmochat_3_6C;
import com.dragon.mmochat.message.Mmochat_3_7C;
import com.dragon.mmochat.message.Mmochat_3_8C;
import com.dragon.mmochat.message.Mmochat_3_9C;
import com.dragon.mmochat.message.Mmochat_5_10S;
import com.dragon.mmochat.message.Mmochat_5_1S;
import com.dragon.mmochat.model.MmochatExtraRandomAward;
import com.dragon.mmochat.model.MmochatTeam;
import com.dragon.mmochat.model.activity.MmochatSystemState;
import com.dragon.mmochat.model.attackMode.MmochatAttackModeOfAddBlood;
import com.dragon.mmochat.model.attackMode.MmochatAttackModeOfNormal;
import com.dragon.mmochat.model.attackMode.MmochatAttackModeOfRescueTeamer;
import com.dragon.mmochat.model.attackMode.MmochatAttackModeOfSpecialSkill;
import com.dragon.mmochat.model.battle.MmochatAction;
import com.dragon.mmochat.model.battle.MmochatBattle;
import com.dragon.mmochat.model.battle.MmochatRoundFrame;
import com.dragon.mmochat.model.battle.MmochatSme;
import com.dragon.mmochat.model.battle.record.MmochatBattleActionClockRecord;
import com.dragon.mmochat.model.battle.record.MmochatBattleChatRecord;
import com.dragon.mmochat.model.battle.record.MmochatBattleRecord;
import com.dragon.mmochat.model.battle.record.MmochatBattleRecordPlayer;
import com.dragon.mmochat.model.battle.record.MmochatBattleRoundRecord;
import com.dragon.mmochat.model.battle.record.MmochatRoleRecord;
import com.dragon.mmochat.model.enumType.MmochatActionType;
import com.dragon.mmochat.model.enumType.MmochatBattleModelType;
import com.dragon.mmochat.model.enumType.MmochatBattleOrderType;
import com.dragon.mmochat.model.enumType.MmochatBattleState;
import com.dragon.mmochat.model.enumType.MmochatBattleType;
import com.dragon.mmochat.model.enumType.MmochatBossLevelType;
import com.dragon.mmochat.model.enumType.MmochatDrugType;
import com.dragon.mmochat.model.enumType.MmochatEquipAttributeType;
import com.dragon.mmochat.model.enumType.MmochatEquipType;
import com.dragon.mmochat.model.enumType.MmochatFamilyType;
import com.dragon.mmochat.model.enumType.MmochatLifeSkillType;
import com.dragon.mmochat.model.enumType.MmochatMaterialType;
import com.dragon.mmochat.model.enumType.MmochatNpcState;
import com.dragon.mmochat.model.enumType.MmochatPetStateType;
import com.dragon.mmochat.model.enumType.MmochatPetType;
import com.dragon.mmochat.model.enumType.MmochatPropType;
import com.dragon.mmochat.model.enumType.MmochatRoleBmpType;
import com.dragon.mmochat.model.enumType.MmochatRoleStateType;
import com.dragon.mmochat.model.enumType.MmochatServerType;
import com.dragon.mmochat.model.enumType.MmochatSkillType;
import com.dragon.mmochat.model.enumType.MmochatSmeResult;
import com.dragon.mmochat.model.enumType.MmochatSmeType;
import com.dragon.mmochat.model.enumType.MmochatSpecialSkillType;
import com.dragon.mmochat.model.enumType.MmochatTaskStateType;
import com.dragon.mmochat.model.enumType.MmochatTaskType;
import com.dragon.mmochat.model.enumType.MmochatTeamStateType;
import com.dragon.mmochat.model.gang.MmochatGang;
import com.dragon.mmochat.model.gang.MmochatGangMember;
import com.dragon.mmochat.model.map.MmochatMap;
import com.dragon.mmochat.model.object.MmochatCommonObject;
import com.dragon.mmochat.model.object.MmochatEquip;
import com.dragon.mmochat.model.object.MmochatPackageGrid;
import com.dragon.mmochat.model.role.MmochatMonster;
import com.dragon.mmochat.model.role.MmochatMonsterFactory;
import com.dragon.mmochat.model.role.MmochatNpc;
import com.dragon.mmochat.model.role.MmochatPet;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.model.role.MmochatRole;
import com.dragon.mmochat.model.role.MmochatTempNpc;
import com.dragon.mmochat.model.scheduleJob.pkGame.activities.MmochatMultiServerWuDaoPkGame;
import com.dragon.mmochat.model.skill.MmochatSkill;
import com.dragon.mmochat.model.skill.MmochatSpecialSkill;
import com.dragon.mmochat.model.task.MmochatNpcBattle;
import com.dragon.mmochat.model.task.MmochatTask;
import com.dragon.mmochat.util.CallLocalFuncTlv;
import com.dragon.mmochat.util.CreateTlvWin;
import com.dragon.mmochat.util.MmochatUtil;
import com.dragon.mmochat.util.SendBigPackUtil;
import com.skymobi.handler.SkymobiHandler;
import com.skymobi.message.SkymobiProtocolMessage;
import com.skymobi.message.widget.AddDataTLV;
import com.skymobi.message.widget.ClearDataTLV;
import com.skymobi.message.widget.CreateMsgBoxTLV;
import com.skymobi.message.widget.SendDataTLV;
import com.skymobi.message.widget.WinType;
import com.skymobi.service.SkymobiService;
import com.skymobi.util.Text;

public class MmochatBattleService {
	private static Logger log = LoggerFactory
			.getLogger(MmochatBattleService.class);

	public static ScheduledExecutorService checkActionTimeOutThread = Executors
			.newScheduledThreadPool(1);
	public static ScheduledExecutorService battleRecordPlayThread = Executors
			.newScheduledThreadPool(1);
	public static ScheduledExecutorService checkBattleRecordLifeThread = Executors
			.newScheduledThreadPool(1);
	public static ScheduledExecutorService updateOrdereThread = Executors
			.newScheduledThreadPool(1);
	public static ScheduledExecutorService updateSqlAfterBattleThread = Executors
			.newScheduledThreadPool(1);

	public static Map<Integer, Integer> expNeedPerLevel = new ConcurrentHashMap<Integer, Integer>();
	public static Map<Integer, MmochatBattle> battles = new ConcurrentHashMap<Integer, MmochatBattle>();

	// 需要保存战斗后数据库的角色队列
	public static ConcurrentLinkedQueue<MmochatPlayer> needToSaveBattleSqlPlayerQueue = new ConcurrentLinkedQueue<MmochatPlayer>();

	// 临时战斗录像数据:战斗ID-->录像
	// 此数据只有用户发送保存指令后才会转成录像数据
	public static Map<Integer, MmochatBattleRecord> tmpBattleRecords = new ConcurrentHashMap<Integer, MmochatBattleRecord>();

	// 战斗录像数据:录像ID-->录像
	public static Map<Integer, MmochatBattleRecord> battleRecords = new ConcurrentHashMap<Integer, MmochatBattleRecord>();

	// 战斗录像播放列表:观看者roleId-->录像播放器
	public static Map<Integer, MmochatBattleRecordPlayer> battleRecordPlayers = new ConcurrentHashMap<Integer, MmochatBattleRecordPlayer>();

	// 战斗后的额外奖励:roleId-->list
	public static Map<Integer, List<MmochatExtraRandomAward>> battleExtraAward = new ConcurrentHashMap<Integer, List<MmochatExtraRandomAward>>();

	public MmochatBattleService() {
		if (!MmochatMain.openMergeServer) {
			// 检查战斗操作超时
			checkActionTimeOutThread.scheduleWithFixedDelay(
					new checkBattleTimeOut(), 2, 2, TimeUnit.SECONDS);

			// 战斗录像播放
			battleRecordPlayThread.scheduleWithFixedDelay(
					new battleRecordPlay(), 2, 2, TimeUnit.SECONDS);

			// 检查录像生命周期
			checkBattleRecordLifeThread.scheduleWithFixedDelay(
					new checkBattleRecordLife(), 2, 2, TimeUnit.MINUTES);

			// 定时更新订单数据
			updateOrdereThread.scheduleWithFixedDelay(new updateOrder(), 5, 5,
					TimeUnit.MINUTES);

			// 定时保存战斗后数据库
			updateSqlAfterBattleThread.scheduleAtFixedRate(
					new saveSqlAfterBattleAction(), 60000, 17000,
					TimeUnit.MILLISECONDS);

			// 装载升级经验
			log.debug("开始装载人物升级经验...");
			expNeedPerLevel.clear();
			File file = new File("base/roleExp.txt");
			int level = 0;
			if (file.exists()) {
				if (file.isFile()) {
					try {
						BufferedReader reader = new BufferedReader(
								new FileReader(file));
						String lineBuf;
						reader.readLine();
						while ((lineBuf = reader.readLine()) != null) {
							if (lineBuf.length() > 0) {
								try {
									String[] str = lineBuf.split("\t");
									level = Integer.parseInt(str[0].trim());
									int value = Integer.parseInt(str[1].trim());
									expNeedPerLevel.put(level, value);
								} catch (NumberFormatException e) {
									e.printStackTrace();
									throw new RuntimeException(
											"人物升级经验.txt有非数字!");
								}
							}
						}
					} catch (FileNotFoundException e) {
						e.printStackTrace();
						throw new RuntimeException("人物升级经验.txt缺失!");
					} catch (IOException e) {
						e.printStackTrace();
						throw new RuntimeException("人物升级经验.txt读取出错!");
					}
				} else {
					throw new RuntimeException("人物升级经验.txt缺失!");
				}
			} else {
				throw new RuntimeException("人物升级经验.txt缺失!");
			}
			log.debug("人物升级经验装载成功!级别数=" + level);
		}
	}

	class checkBattleTimeOut implements Runnable {
		@Override
		public void run() {
			try {
				for (MmochatBattle battle : battles.values()) {
					battle.checkBattleStateTimeOut();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 播放录像
	class battleRecordPlay implements Runnable {
		@Override
		public void run() {
			try {
				for (MmochatBattleRecordPlayer recordPlayer : battleRecordPlayers
						.values()) {
					if (System.currentTimeMillis()
							- recordPlayer.getPlayStartTick() > 2 * MmochatConstant.MS_PER_HOUR) {
						// 播放时间超过2小时，则直接结束
						recordPlayer.quit();
						battleRecordPlayers.remove(recordPlayer.getRoleId());
						continue;
					}
					boolean over = recordPlayer.play();
					if (over) {
						battleRecordPlayers.remove(recordPlayer.getRoleId());
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 检查玩家录像生命周期
	class checkBattleRecordLife implements Runnable {
		@Override
		public void run() {
			try {
				if (battleRecords.size() <= MmochatConstant.maxRecordNumShow) {
					return;
				}
				List<MmochatBattleRecord> records = new ArrayList<MmochatBattleRecord>();
				for (MmochatBattleRecord r : battleRecords.values()) {
					// 玩家录像
					if (r.getType() != MmochatBattleType.武道会比赛
							&& r.getType() != MmochatBattleType.个人争霸赛
							&& r.getType() != MmochatBattleType.天下第一争霸赛
							&& r.getType() != MmochatBattleType.跨服武道会比赛) {
						records.add(r);
					}
				}
				// 如果录像数量超过50个，则按规则删除:
				// 按时间先后，将较早的录像中，符合“没有人在观看此录像，且连续20分钟没有将此战斗发送到世界聊天中”
				int delNum = records.size() - MmochatConstant.maxRecordNumShow;
				if (delNum <= 0) {
					return;
				}
				Collections.sort(records);
				Collections.reverse(records);
				int count = 0;
				for (MmochatBattleRecord r : records) {
					if (r.isAlive()) {
						continue;
					}
					boolean hasWatch = false;
					for (MmochatBattleRecordPlayer p : battleRecordPlayers
							.values()) {
						if (p.getBattleRecordId() == r.getId()) {
							hasWatch = true;
							break;
						}
					}
					if (!hasWatch) {
						battleRecords.remove(r.getId());
						count++;
					}
					if (count >= delNum) {
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 观看录像
	public static void watchBattleRecord(int roleId, int battleRecordId) {
		MmochatBattleRecordPlayer record = battleRecordPlayers.get(roleId);
		if (record != null) {
			// 先关闭旧的
			record.quit();
			battleRecordPlayers.remove(record.getRoleId());
		}
		MmochatBattleRecord battle = MmochatBattleService.battleRecords
				.get(battleRecordId);
		if (battle != null) {
			record = new MmochatBattleRecordPlayer();
			record.setRoleId(roleId);
			record.setBattleRecordId(battleRecordId);
			battleRecordPlayers.put(record.getRoleId(), record);
			record.start();
		}
	}

	public static void saveSqlAfterBattle(MmochatPlayer me) {
		if (me == null) {
			return;
		}
		// 放入保存队列中
		if (!needToSaveBattleSqlPlayerQueue.contains(me)
				&& !MmochatGmService.isSystemExit()) {
			needToSaveBattleSqlPlayerQueue.add(me);
		}
	}

	// 平均每8秒最多能执行大约1次，在高峰期，1000人同时打怪情况下，平均每人133分钟会保存一次数据库
	// 由于退出时也会进行数据保存，故此数实时性要求不高
	class saveSqlAfterBattleAction implements Runnable {
		@Override
		public void run() {
			try {
				if (System.currentTimeMillis() < MmochatConstant.startSaveSqlAfterJobTick) {
					return;
				}
				if (!MmochatConstant.saveSqlAfterActiveLock) {
					needToSaveBattleSqlPlayerQueue.clear();
					return;
				}
				MmochatPlayer me = needToSaveBattleSqlPlayerQueue.poll();
				try {
					if (me != null) {
						MmochatPlayer he = MmochatMainService.offlinePlayers
								.get(me.getRoleId());
						if (he != null && me != he) {
							me = he;
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 为防止死锁等导致一条操作无法结束，每次启动新的线程来执行
				new Thread(new doSql(me)).start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	class doSql extends Thread {
		MmochatPlayer me = null;

		public doSql(MmochatPlayer m) {
			me = m;
		}

		public void run() {
			try {
				if (me != null) {
					MmochatDao.batchUpdateSqlAfterBattle(me);
					log.debug(me.getName() + "执行batchUpdateSqlAfterBattle操作!");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	class updateOrder implements Runnable {
		@Override
		public void run() {
			try {
				long t = System.currentTimeMillis();
				for (Entry<Long, Long> entry : ChargeOrderService.successOrders
						.entrySet()) {
					long orderTime = entry.getValue();
					if (t - orderTime >= ChargeOrderService.orderSaveTime) {
						ChargeOrderService.successOrders.remove(entry.getKey());
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 获取人物升级所需经验; liefTurn:转生次数
	public static int getHumanExpNeedToUplevel(int curLevel, int lifeTurn) {
		int nextLevel = curLevel + 1;
		if (curLevel > MmochatConstant.maxLevel
				|| lifeTurn > MmochatConstant.maxLifeTurn) {
			return 0;
		}
		int trueLevel = nextLevel + lifeTurn * 10;
		try {
			return expNeedPerLevel.get(trueLevel);
		} catch (Exception e) {
			e.printStackTrace();
			return 2000000000;
		}
	}

	// 获取宠物升级所需经验
	public static int getPetExpNeedToUplevel(int curLevel, int lifeTurn) {
		return (int) (getHumanExpNeedToUplevel(curLevel, lifeTurn) * MmochatConstant.petExpPercentOfPerson);
	}

	// 计算掉血量
	/*
	 * 物攻掉血=(物伤-实际物防)X倍数X(1-物免%)...MAX(0,物理致命一击-物理致命抵抗)...MAX(0,物理暴击-物理暴击抵抗)
	 * 实际物防：物理破防，则为0;否则为物防; 实际掉血＝MAX(攻方神圣物理伤害, 物攻掉血)
	 */
	public static int[] calPhysicalHurt(MmochatRole attacker,
			MmochatRole defender) {
		return calPhysicalHurt(attacker, defender,
				MmochatConstant.physicalAttackParam);
	}

	public static int[] calPhysicalHurt(MmochatRole attacker,
			MmochatRole defender, double attackParam) {
		int[] ret = new int[2];
		ret[1] = 0;
		// 无视伤害
		int noHurtPercent = defender
				.getCommonEquipAttributeValue(MmochatEquipAttributeType.无视伤害);
		if (MmochatUtil.isInPercent(noHurtPercent)) {
			ret[0] = 0;
			return ret;
		}

		double hurt = 0;
		int attacker_pAttack = attacker.getPhysicalAttack();// 物伤
		int defender_pDefence = 0;// 物防
		int attacker_pDefendIgnore = attacker.getPhysicalDefendIgnore();// 物理破防
		int defender_physicalDefendPercent = defender
				.getPhysicalDefendPercent(); // 物免
		if (!MmochatUtil.isInPercent(attacker_pDefendIgnore)) {
			// 不破防
			defender_pDefence = defender.getPhysicalDefend();
		}
		double hurtParam = 1; // 伤害倍数
		int attacker_pDoubleAttack = attacker.getPhysicalDoubleAttack(); // 获取物理致命一击(2倍伤害)
		int defender_pDoubleAttackDefend = defender
				.getPhysicalDoubleAttackDefend();// 获取物理致命一击抵抗
		int percent = Math.min(attacker_pDoubleAttack
				- defender_pDoubleAttackDefend, 75);
		// 武魂技能：2.5倍物伤
		int highHitPercent = attacker
				.getCommonEquipAttributeValue(MmochatEquipAttributeType.物伤高倍);

		if (MmochatUtil.isInPercent(highHitPercent)) {
			// 2.5倍物伤
			hurtParam = 2.5;
		} else if (MmochatUtil.isInPercent(percent)) {
			// 致命一击
			hurtParam = 2;
		} else {
			int attacker_pDeadlyAttack = attacker.getPhysicalDeadlyAttack();// 获取物理暴击(1.5倍伤害)
			int defender_pDeadlyAttackDefend = defender
					.getPhysicalDeadlyAttackDefend();// 获取物理暴击抵抗
			percent = Math.min(attacker_pDeadlyAttack
					- defender_pDeadlyAttackDefend, 75);
			if (MmochatUtil.isInPercent(percent)) {
				// 暴击
				hurtParam = 1.5;
			}
		}
		hurt = (attacker_pAttack - defender_pDefence) * hurtParam;
		if (attacker instanceof MmochatPlayer) {
			hurt = hurt * attackParam;
		}
		hurt = hurt * (100 - defender_physicalDefendPercent) / 100.0;

		if (defender.isUseDefendInPk() && !defender.hasSme(MmochatSmeType.封印)
				&& !defender.hasSme(MmochatSmeType.冰冻)
				&& !defender.hasSme(MmochatSmeType.混乱)) {
			// 防御状态，则掉血量减少
			hurt = hurt * 0.6;
		}

		// 神圣物理伤害
		int minAttack = (int) (attacker_pAttack
				* attacker.getSuperPhysicalAttack() / 100.0);
		hurt = Math.max(hurt, minAttack);

		// 如果对方是冰冻状态
		if (defender.hasSme(MmochatSmeType.冰冻)) {
			hurt = hurt * MmochatConstant.freezeAttackParam;
		}

		// 波动
		hurt = MmochatUtil.getWaveValue((int) hurt, 5);
		hurt = Math.max(1, hurt);

		// 三魂丹效果
		if (defender.hasSme(MmochatSmeType.三魂丹)) {
			MmochatSme sme = defender.getSme().get(MmochatSmeType.三魂丹);
			if (sme != null) {
				int effectValue = (int) sme.getValue();
				if (effectValue >= hurt) {
					// 伤害抵消
					sme.addValue(-1 * hurt);
					hurt = 0;
				} else if (effectValue > 0) {
					sme.setValue(0);
					hurt -= effectValue;
				}
				sme.decreaseDefendTimes();
				if (sme.getDefendTimes() <= 0 || sme.getValue() <= 0) {
					defender.getSme().remove(MmochatSmeType.三魂丹);
					// 被障碍时不变身，防止障碍动画消失
					if (defender.hasSme(MmochatSmeType.封印)
							|| defender.hasSme(MmochatSmeType.冰冻)
							|| defender.hasSme(MmochatSmeType.混乱)) {
						ret[1] = 0;
					} else {
						ret[1] = 1;
					}
				}
			}
		}
		ret[0] = (int) hurt;
		return ret;
	}

	// 计算掉血量
	/*
	 * 法攻掉血=(法伤-实际法防)X倍数X技能等级伤害系数X(1-抗法%)X(1-法免%)...MAX(0,法术致命一击-法术致命抵抗)...MAX(0,
	 * 法术暴击-法术暴击抵抗) 实际法防：法术破防，则为0;否则为法防;宠物法攻,技能等级伤害系数=0.75;实际掉血＝MAX(攻方神圣法术伤害,
	 * 法攻掉血)
	 */
	public static int[] calMagicHurt(MmochatRole attacker,
			MmochatRole defender, MmochatSkill skill) {
		return calMagicHurt(attacker, defender, skill, 1);
	}

	public static int[] calMagicHurt(MmochatRole attacker,
			MmochatRole defender, MmochatSkill skill, double attackParam) {
		int[] ret = new int[2];
		ret[1] = 0;
		// 无视伤害
		int noHurtPercent = defender
				.getCommonEquipAttributeValue(MmochatEquipAttributeType.无视伤害);
		if (MmochatUtil.isInPercent(noHurtPercent)) {
			ret[0] = 0;
			return ret;
		}

		double hurt = 0;
		int attacker_mAttack = attacker.getSpritAttack();// 法伤
		int defender_mDefence = 0;// 法防
		int attacker_mDefendIgnore = attacker.getMagicDefendIgnore();// 法术破防
		int defender_magicDefendPercent = defender.getMagicDefendPercent();
		if (!MmochatUtil.isInPercent(attacker_mDefendIgnore)) {
			// 不破防
			defender_mDefence = defender.getMagicDefend();
		}
		double hurtParam = 1; // 伤害倍数
		int attacker_mDoubleAttack = attacker.getMagicDoubleAttack(); // 获取法术致命一击(2倍伤害)
		int defender_mDoubleAttackDefend = defender
				.getMagicDoubleAttackDefend();// 获取法术致命一击抵抗
		int percent = Math.min(attacker_mDoubleAttack
				- defender_mDoubleAttackDefend, 75);
		if (MmochatUtil.isInPercent(percent)) {
			// 致命一击
			hurtParam = 2;
		} else {
			int attacker_mDeadlyAttack = attacker.getMagicDeadlyAttack();// 获取法术暴击(1.5倍伤害)
			int defender_mDeadlyAttackDefend = defender
					.getMagicDeadlyAttackDefend();// 获取法术暴击抵抗
			percent = Math.min(attacker_mDeadlyAttack
					- defender_mDeadlyAttackDefend, 75);
			if (MmochatUtil.isInPercent(percent)) {
				// 暴击
				hurtParam = 1.5;
			}
		}
		double skillHurtParam = 1; // 技能等级伤害系数
		if (attacker instanceof MmochatMonster
				|| attacker instanceof MmochatPet) {
			skillHurtParam = MmochatConstant.monsterSkillHurtParam;
		} else {
			skillHurtParam = skill.getEffectValue() / 100.0;
		}
		hurt = (attacker_mAttack - defender_mDefence) * hurtParam
				* skillHurtParam;
		hurt = Math.max(1, hurt);

		// 抗法
		int attacker_ingoreAntiSkill = 0; // 忽视抗法
		int defender_antiSkill = 0;// 抗法
		switch (skill.getType().getSkillFamily()) {
		case 阐教:
			attacker_ingoreAntiSkill = attacker.getIgnoreAntiGodSkill();
			defender_antiSkill = defender.getAntiGodSkill();
			break;
		case 人教:
			attacker_ingoreAntiSkill = attacker.getIgnoreAntiHumanSkill();
			defender_antiSkill = defender.getAntiHumanSkill();
			break;
		case 截教:
			attacker_ingoreAntiSkill = attacker.getIgnoreAntiDevilSkill();
			defender_antiSkill = defender.getAntiDevilSkill();
			break;
		default:
			break;
		}
		int antiSkill = Math.max(0, defender_antiSkill
				- attacker_ingoreAntiSkill);
		antiSkill = Math.min(antiSkill, 80);
		hurt = hurt * (100 - antiSkill) / 100.0;
		hurt = Math.max(1, hurt);

		// 法免
		hurt = hurt * (100 - defender_magicDefendPercent) / 100.0;

		if (defender.isUseDefendInPk() && !defender.hasSme(MmochatSmeType.封印)
				&& !defender.hasSme(MmochatSmeType.冰冻)
				&& !defender.hasSme(MmochatSmeType.混乱)) {
			// 防御状态，则掉血量减少
			hurt = hurt * 0.7;
		}

		// 神圣法术伤害
		int minAttack = (int) (attacker_mAttack
				* attacker.getSuperSpritAttack() / 100.0);
		hurt = Math.max(hurt, minAttack);

		// 如果对方是冰冻状态
		if (defender.hasSme(MmochatSmeType.冰冻)) {
			hurt = hurt * MmochatConstant.freezeAttackParam;
		}

		// 波动
		hurt = MmochatUtil.getWaveValue((int) hurt, 5);
		hurt = Math.max(1, hurt);

		hurt = hurt * attackParam;

		// 七魄丹效果
		if (defender.hasSme(MmochatSmeType.七魄丹)) {
			MmochatSme sme = defender.getSme().get(MmochatSmeType.七魄丹);
			if (sme != null) {
				int effectValue = (int) sme.getValue();
				if (effectValue >= hurt) {
					// 伤害抵消
					sme.addValue(-1 * hurt);
					hurt = 0;
				} else if (effectValue > 0) {
					sme.setValue(0);
					hurt -= effectValue;
				}
				sme.decreaseDefendTimes();
				if (sme.getDefendTimes() <= 0 || sme.getValue() <= 0) {
					defender.getSme().remove(MmochatSmeType.七魄丹);
					// 被障碍时不变身，防止障碍动画消失
					if (defender.hasSme(MmochatSmeType.封印)
							|| defender.hasSme(MmochatSmeType.冰冻)
							|| defender.hasSme(MmochatSmeType.混乱)) {
						ret[1] = 0;
					} else {
						ret[1] = 1;
					}
				}
			}
		}
		ret[0] = (int) hurt;

		return ret;
	}

	// 判断是否命中
	// 0:物理攻击； 1:法术攻击
	// 闪避率 = （闪避 – 命中）/10000 X 100%；（若被攻击方的闪避小于攻击方的命中即闪避率为负数，则必命中）
	// 暂定 法术闪避 = 闪避率 X 50%）
	// 实际命中 ＝ 1 – 闪避率；
	public static boolean calHit(MmochatRole attacker, MmochatRole defender,
			int attackType) {
		int avoid;
		if (attackType == 1) {
			avoid = defender.getMagicAvoid();
		} else {
			avoid = defender.getPhysicalAvoid();
		}
		double hitRate = 100 - avoid;
		return MmochatUtil.isInPercent(hitRate);
	}

	// 等级差经验削减计算
	// 暂定：人物或宠与怪物相差6级以内可获得全经验，7级获得90%，8级获得80%，9级获得70%，10级或以上无经验。
	public static int getRealExp(int exp, MmochatRole role,
			MmochatRole targetRole) {
		int targetLevel = targetRole.getLevel() + targetRole.getLife_turn()
				* 10;
		int myLevel = role.getLevel() + role.getLife_turn() * 10;
		int deltaLevel = Math.abs(myLevel - targetLevel);
		if (deltaLevel <= 6) {
			return exp;
		} else if (deltaLevel == 7) {
			return (int) (exp * 0.9);
		} else if (deltaLevel == 8) {
			return (int) (exp * 0.8);
		} else if (deltaLevel == 9) {
			return (int) (exp * 0.7);
		} else if (deltaLevel == 10) {
			return (int) (exp * 0.6);
		} else if (deltaLevel <= 15) {
			return (int) (exp * 0.5);
		} else {
			return 1;
		}
	}

	public static int getRealExp2(int exp, MmochatRole role, int targetLevel) {
		int myLevel = role.getLevel() + role.getLife_turn() * 10;
		int deltaLevel = Math.abs(myLevel - targetLevel);
		if (deltaLevel <= 6) {
			return exp;
		} else if (deltaLevel == 7) {
			return (int) (exp * 0.9);
		} else if (deltaLevel == 8) {
			return (int) (exp * 0.8);
		} else if (deltaLevel == 9) {
			return (int) (exp * 0.7);
		} else if (deltaLevel == 10) {
			return (int) (exp * 0.6);
		} else if (deltaLevel <= 15) {
			return (int) (exp * 0.5);
		} else {
			return 1;
		}
	}

	// 标准道行(天)
	public static int getStandardDao(int level, int life_turn) {
		return (int) Math.max(1, ((level + 10 * life_turn)
				* (level + 10 * life_turn) * (level + 10 * life_turn) * 0.29));
	}

	// 等级差道行削减计算
	// 暂定：人物或宠与怪物相差6级以内可获得全道，7级获得90%，8级获得80%，9级获得70%，10级或以上无经验。
	public static int getRealDaoOfLevel(int dao, MmochatRole role,
			MmochatRole targetRole) {
		int targetLevel = targetRole.getLevel() + targetRole.getLife_turn()
				* 10;
		int myLevel = role.getLevel() + role.getLife_turn() * 10;
		int deltaLevel = Math.abs(myLevel - targetLevel);
		if (deltaLevel <= 6) {
			return dao;
		} else if (deltaLevel == 7) {
			return (int) (dao * 0.9);
		} else if (deltaLevel == 8) {
			return (int) (dao * 0.8);
		} else if (deltaLevel == 9) {
			return (int) (dao * 0.7);
		} else if (deltaLevel == 10) {
			return (int) (dao * 0.6);
		} else if (deltaLevel <= 15) {
			return (int) (dao * 0.5);
		} else {
			return 1;
		}
	}

	public static int getRealDaoOfLevel2(int dao, MmochatRole role,
			int targetLevel) {
		int myLevel = role.getLevel() + role.getLife_turn() * 10;
		int deltaLevel = Math.abs(myLevel - targetLevel);
		if (deltaLevel <= 6) {
			return dao;
		} else if (deltaLevel == 7) {
			return (int) (dao * 0.9);
		} else if (deltaLevel == 8) {
			return (int) (dao * 0.8);
		} else if (deltaLevel == 9) {
			return (int) (dao * 0.7);
		} else if (deltaLevel == 10) {
			return (int) (dao * 0.6);
		} else if (deltaLevel <= 15) {
			return (int) (dao * 0.5);
		} else {
			return 1;
		}
	}

	// 玩家实际获得的道行
	public static int getRealDao(MmochatRole me, int dao) {
		return getRealDao(me, (long) dao);
	}

	public static int getRealDao(MmochatRole me, long dao) {
		if (me == null || dao == 0) {
			return 0;
		}
		int standDao = getStandardDao(me.getLevel(), me.getLife_turn());
		if (standDao <= 0) {
			return 1;
		}
		double times = 1.0 * me.getDao() / standDao;
		if (times > 1) {
			dao = (long) (dao * Math.pow(0.6, times - 1));
		}
		dao = Math.min(dao, Integer.MAX_VALUE);
		dao = Math.max(1, dao);
		if (dao == 1) {
			if (me instanceof MmochatPlayer) {
				MmochatPlayer role = (MmochatPlayer) me;

				// 系统双倍
				if (MmochatSystemState.isSystemDoubleAward()
						|| role.hasPropEffect(MmochatPropType.系统双倍令
								.getEffectKey())) {
					dao *= MmochatSystemState.getSystemawardvalue();
				}

				// 道具:时间双倍
				if (role.hasPropEffect(MmochatPropType.天尊令.getEffectKey())) {
					dao *= 2;
				}
			}
		}
		return (int) dao;
	}

	// A对B进行障碍技能,计算成功率
	public static int getLimitRate(MmochatRole fighter, MmochatRole defender,
			MmochatSkill skill) {
		if (fighter == null || defender == null) {
			return 0;
		}
		// 基础成功率
		double fighterDao = Math.max(1, fighter.getDao());
		double defenderDao = Math.max(1, defender.getDao());
		double baseRate = skill.getEffectValue();// 40~60
		baseRate = Math.min(baseRate, 50);// 技能成功率最大限制为50%

		if (fighterDao >= defenderDao) {
			baseRate = baseRate + (fighterDao / defenderDao - 1) / 0.1 * 10;
		} else {
			baseRate = baseRate - (1 - fighterDao / defenderDao) / 0.1 * 15;
		}
		// baseRate = Math.max(0, baseRate);
		// baseRate = Math.min(100, baseRate);

		// 装备成功率:A障碍B装备附加成功率=A装备强力障碍-MAX(0,B装备抗障碍-A装备忽视抗障碍)
		float equipRate = 0;
		switch (fighter.getFamily()) {
		case 阐教: {
			equipRate = fighter.getStrengthenSeal()
					- Math.max(0, defender.getAntiSeal()
							- fighter.getIgnoreAntiSeal());
			break;
		}
		case 人教: {
			equipRate = fighter.getStrengthenFreeze()
					- Math.max(0, defender.getAntiFreeze()
							- fighter.getIgnoreAntiFreeze());
			break;
		}
		case 截教: {
			equipRate = fighter.getStrengthenConfuse()
					- Math.max(0, defender.getAntiConfuse()
							- fighter.getIgnoreAntiConfuse());
			break;
		}
		default:
			break;
		}
		int finalRate = (int) (baseRate + equipRate);
		finalRate = Math.max(0, finalRate);
		finalRate = Math.min(100, finalRate);
		return finalRate;
	}

	// A对B障碍成功后，障碍状态保持几个回合
	public static int getLimitKeepRounds(MmochatRole fighter,
			MmochatRole defender, MmochatSkill skill) {
		int fighterDao = Math.max(1, fighter.getDao());
		int defenderDao = Math.max(1, defender.getDao());
		double times = 1.0 * fighterDao / defenderDao;
		int round;
		int skillKeepRound = skill.getKeepRound();// 2-3
		if (times < 0.8) {
			// 0-0.8
			round = skillKeepRound - 2;
		} else if (times < 1.2) {
			// 0.8-1.2
			round = skillKeepRound - 1;
			round = Math.max(2, round);// 至少2个回合
		} else if (times < 2) {
			// 1.2-2
			round = skillKeepRound;
		} else {
			// 2-max
			round = skillKeepRound + 1;
		}
		round = Math.max(1, round);
		round = Math.min(6, round);
		return round;
	}

	// 计算常规怪物经验产出
	public static int getMonsterAwardExp(List<MmochatMonster> monsters,
			MmochatRole me, int teamNum) {
		if (monsters == null || monsters.size() == 0 || me == null) {
			return 0;
		}
		int sumExp = 0;
		for (MmochatMonster monster : monsters) {
			sumExp += getRealExp(monster.getKillExp(), me, monster);
		}
		sumExp = MmochatUtil.getTeamAward(sumExp, teamNum);
		sumExp = Math.max(sumExp, 1);
		return sumExp;
	}

	// 计算常规怪物材料产出
	public static Map<MmochatMaterialType, Integer> getMonsterAwardMaterials(
			List<MmochatMonster> monsters) {
		Map<MmochatMaterialType, Integer> materials = new ConcurrentHashMap<MmochatMaterialType, Integer>();
		if (monsters == null || monsters.size() == 0) {
			return materials;
		}
		for (MmochatMonster monster : monsters) {
			// 12%机率掉落材料
			for (MmochatMaterialType type : monster.getMaterials()) {
				if (MmochatUtil.isInPercent(12)) {
					Integer curNum = materials.get(type);
					if (curNum != null) {
						curNum++;
						materials.put(type, curNum);
					} else {
						materials.put(type, 1);
					}
				}
			}
		}
		return materials;
	}

	// 计算常规怪物装备产出
	public static List<MmochatEquip> getMonsterAwardEquips(
			List<MmochatMonster> monsters) {
		List<MmochatEquip> equips = new ArrayList<MmochatEquip>();
		if (monsters == null || monsters.size() == 0) {
			return equips;
		}
		for (MmochatMonster monster : monsters) {
			// 0.1%机率蓝装,0.05%机率金装
			MmochatEquip equip = MmochatEquipService.getRandEquip(monster
					.getLevel(), monster.getLevel() + 10, 0, 0.1, 0.05);
			if (equip != null) {
				equips.add(equip);
			}
		}
		return equips;
	}

	// 计算常规怪物游戏币产出
	public static int getMonsterAwardSmallMoney(List<MmochatMonster> monsters,
			int teamNum) {
		int smallMoney = 0;
		if (monsters == null || monsters.size() == 0) {
			return smallMoney;
		}

		for (MmochatMonster monster : monsters) {
			smallMoney += monster.getKillSmallMoney();
		}
		smallMoney = smallMoney / teamNum;
		smallMoney = Math.max(smallMoney, 1);

		return smallMoney;
	}

	// PVP战斗
	// 队长站中间
	public static MmochatBattle enterPVPBattle(int mapId, byte line,
			List<MmochatPlayer> requestRoles, List<MmochatPlayer> targetRoles,
			MmochatBattleType battleType) {
		if (requestRoles == null || targetRoles == null
				|| requestRoles.size() == 0 || targetRoles.size() == 0) {
			return null;
		}
		// 让队长站中间
		String name1 = "", name2 = "";
		try {
			for (MmochatPlayer me : requestRoles) {
				if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
					requestRoles.remove(me);
					requestRoles.add(0, me);
					name1 = me.getName();
					break;
				}
			}
			if (requestRoles.size() > 1) {
				name1 += "(队)";
			}
			for (MmochatPlayer me : targetRoles) {
				if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
					targetRoles.remove(me);
					targetRoles.add(0, me);
					name2 = me.getName();
					break;
				}
			}
			if (targetRoles.size() > 1) {
				name2 += "(队)";
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);
			newBattle.setType(battleType);
			for (MmochatPlayer player : requestRoles) {
				player.stopDeal();
				if (player.lockState(MmochatRoleStateType.进入战斗时)) {
					if (!player.isInBattle() && player.getMapId() == mapId
							&& player.getLine() == line) {
						newBattle.addLeftTeam(player, true);
					}
					player.unLockState();
				} else {
					log.debug(player.getName() + "当前状态为:"
							+ player.getState().toString() + ",队伍的mapId="
							+ mapId + ", 此人的mapId=" + player.getMapId()
							+ ",无法进入战斗!");
				}
			}
			for (MmochatPlayer player : targetRoles) {
				player.stopDeal();
				if (player.lockState(MmochatRoleStateType.进入战斗时)) {
					if (!player.isInBattle() && player.getMapId() == mapId
							&& player.getLine() == line) {
						newBattle.addRightTeam(player, true);
					}
					player.unLockState();
				} else {
					log.debug(player.getName() + "当前状态为:"
							+ player.getState().toString() + ",队伍的mapId="
							+ mapId + ", 此人的mapId=" + player.getMapId()
							+ ",无法进入战斗!");
				}
			}
			if (newBattle.getLeftTeam().size() == 0
					|| newBattle.getRightTeam().size() == 0) {
				log.debug("一边队伍无人参战，切磋无法进行。");
				newBattle.closeBattle();
				return null;
			}
			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			for (MmochatRole player : requestRoles) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}
			for (MmochatRole player : targetRoles) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(battleType);
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role.getId());
						r.setBmpType(role.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role.getName();
							r.setName(name);
						} else {
							r.setName(role.getName());
						}
						r.setSmeValue(role.getSmeValue());
						r.setTotalBlood(role.getTotalBlood());
						r.setCurPkBlood(role.getCurPkBlood());
						r.setTotalSprit(role.getTotalSprit());
						r.setCurPkSprit(role.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
			return newBattle;
		} catch (Exception e) {
			e.printStackTrace();
			for (MmochatPlayer player : requestRoles) {
				player.unLockState();
			}
			for (MmochatPlayer player : targetRoles) {
				player.unLockState();
			}
			return null;
		}
	}

	// PVE玩家打怪
	public static void enterMonsterPk(int mapId, byte line,
			List<MmochatPlayer> players, List<MmochatMonster> monsters) {
		enterMonsterPk(mapId, line, players, monsters, MmochatBattleType.野外打怪);
	}

	public static void enterMonsterPk(int mapId, byte line,
			List<MmochatPlayer> players, List<MmochatMonster> monsters,
			MmochatBattleType battleType) {
		if (players == null || players.size() == 0 || monsters == null
				|| monsters.size() == 0) {
			return;
		}
		// 让队长站中间
		MmochatPlayer teamLeader = null;
		String name1 = "";
		try {
			for (MmochatPlayer me : players) {
				if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
					players.remove(me);
					players.add(0, me);
					teamLeader = me;
					name1 = me.getName();
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (players.size() > 1) {
			name1 += "(队)";
		}

		if (teamLeader == null) {
			teamLeader = new MmochatPlayer();
		}

		try {
			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);
			newBattle.setType(battleType);
			synchronized (teamLeader) {
				for (MmochatPlayer player : players) {
					player.stopDeal();
					if (player.lockState(MmochatRoleStateType.进入战斗时)) {
						if (!player.isInBattle() && player.getMapId() == mapId
								&& player.getLine() == line) {
							newBattle.addLeftTeam(player, false);
						}
						player.unLockState();
					} else {
						log.debug(player.getName() + "当前状态为:"
								+ player.getState().toString() + ",队伍的mapId="
								+ mapId + ", 此人的mapId=" + player.getMapId()
								+ ",无法进入战斗!");
					}
				}
			}
			if (newBattle.getLeftTeam().size() == 0) {
				if (newBattle.getLeftTeam().size() == 0
						|| newBattle.getRightTeam().size() == 0) {
					newBattle.closeBattle();
					log.debug("一边队伍无人参战，打怪无法进行。");
					return;
				}
			}
			String name2 = "";
			for (MmochatMonster monster : monsters) {
				newBattle.addRightTeam(monster, false);
				name2 = monster.getName();
			}
			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			for (MmochatRole player : players) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(battleType);
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role.getId());
						r.setBmpType(role.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role.getName();
							r.setName(name);
						} else {
							r.setName(role.getName());
						}
						r.setSmeValue(role.getSmeValue());
						r.setTotalBlood(role.getTotalBlood());
						r.setCurPkBlood(role.getCurPkBlood());
						r.setTotalSprit(role.getTotalSprit());
						r.setCurPkSprit(role.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
		} catch (Exception e) {
			e.printStackTrace();
			for (MmochatPlayer player : players) {
				player.unLockState();
			}
		}
	}

	// 与NPC的任务战斗
	public static MmochatBattle enterNpcPk(int mapId, byte line,
			List<MmochatPlayer> players, int taskerRoleId, MmochatTask task,
			Integer npcId) {
		if (players == null || players.size() == 0 || task == null) {
			return null;
		}

		// 让队长站中间
		String name1 = "";
		try {
			for (MmochatPlayer me : players) {
				if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
					players.remove(me);
					players.add(0, me);
					name1 = me.getName();
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (players.size() > 1) {
			name1 += "(队)";
		}

		try {
			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);
			newBattle.setTaskBattle_taskId(task.getTaskId());
			newBattle.setTaskBattle_roleId(taskerRoleId);
			if (npcId != null) {
				newBattle.setTmpNpcId(npcId);
			}

			// 任务类型名和战斗类型名要一致
			newBattle.setType(MmochatBattleType.valueOf(task.getTaskType()
					.toString()));

			for (MmochatPlayer player : players) {
				player.stopDeal();
				if (player.lockState(MmochatRoleStateType.进入战斗时)) {
					if (!player.isInBattle() && player.getMapId() == mapId
							&& player.getLine() == line) {
						newBattle.addLeftTeam(player, false);
					}
					player.unLockState();
				} else {
					log.debug(player.getName() + "当前状态为:"
							+ player.getState().toString() + ",队伍的mapId="
							+ mapId + ", 此人的mapId=" + player.getMapId()
							+ ",无法进入战斗!");
				}
			}

			if (newBattle.getLeftTeam().size() == 0) {
				if (newBattle.getLeftTeam().size() == 0
						|| newBattle.getRightTeam().size() == 0) {
					newBattle.closeBattle();
					log.debug("一边队伍无人参战，NPC战斗无法进行。");
					return null;
				}
			}

			int teamMaxLevel = 0;// 队伍最高等级
			Integer teamLeaderLevel = null;// 队长等级
			for (MmochatPlayer me : players) {
				teamMaxLevel = Math.max(teamMaxLevel, me.getTrueLevel());
				if (MmochatTeamService.getTeamState(me) == MmochatTeamStateType.队长) {
					teamLeaderLevel = me.getTrueLevel();
				}
			}
			if (teamLeaderLevel == null) {
				teamLeaderLevel = teamMaxLevel;
			}

			MmochatMonsterFactory bossFactory = task.getFinish_need_battles()
					.getBoss();
			if (bossFactory.getLevelType() == MmochatBossLevelType.队伍最高等级) {
				bossFactory.setLevel(teamMaxLevel);
				bossFactory
						.setDao((int) (bossFactory.getDaoParam() * MmochatBattleService
								.getStandardDao(teamMaxLevel, 0)));
			} else if (bossFactory.getLevelType() == MmochatBossLevelType.队长等级) {
				bossFactory.setLevel(teamLeaderLevel);
				bossFactory
						.setDao((int) (bossFactory.getDaoParam() * MmochatBattleService
								.getStandardDao(teamLeaderLevel, 0)));
			}
			String name2 = "";
			MmochatMonster boss = MmochatEquipService
					.setMonsterBattleParam(bossFactory);
			name2 += boss.getName();
			newBattle.addRightTeam(boss, false);
			log.debug(boss.getName() + ":血" + boss.getTotalBlood() + "，物:"
					+ boss.getPhysicalAttack() + "，法:" + boss.getSpritAttack());

			for (MmochatMonsterFactory monsterFactory : task
					.getFinish_need_battles().getSmallBoss()) {
				if (monsterFactory == null) {
					continue;
				}
				if (monsterFactory.getLevelType() == MmochatBossLevelType.队伍最高等级) {
					monsterFactory.setLevel(teamMaxLevel);
					monsterFactory
							.setDao((int) (monsterFactory.getDaoParam() * MmochatBattleService
									.getStandardDao(teamMaxLevel, 0)));
				} else if (monsterFactory.getLevelType() == MmochatBossLevelType.队长等级) {
					monsterFactory.setLevel(teamLeaderLevel);
					monsterFactory
							.setDao((int) (monsterFactory.getDaoParam() * MmochatBattleService
									.getStandardDao(teamLeaderLevel, 0)));
				}
				MmochatMonster monster = MmochatEquipService
						.setMonsterBattleParam(monsterFactory);
				newBattle.addRightTeam(monster, false);
				log.debug(monster.getName() + ":血" + monster.getTotalBlood()
						+ "，物:" + monster.getPhysicalAttack() + "，法:"
						+ monster.getSpritAttack());
			}

			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			for (MmochatRole player : players) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(newBattle.getType());
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role.getId());
						r.setBmpType(role.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role.getName();
							r.setName(name);
						} else {
							r.setName(role.getName());
						}
						r.setSmeValue(role.getSmeValue());
						r.setTotalBlood(role.getTotalBlood());
						r.setCurPkBlood(role.getCurPkBlood());
						r.setTotalSprit(role.getTotalSprit());
						r.setCurPkSprit(role.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
			return newBattle;
		} catch (Exception e) {
			e.printStackTrace();
			for (MmochatPlayer player : players) {
				player.unLockState();
			}
			return null;
		}
	}

	// 与NPC的战斗，并且直接使用MmochatMonsterFactory中的MmochatMonster参数作为怪物数据
	public static MmochatBattle enterNpcPkWithMonsterData(int mapId, byte line,
			List<MmochatPlayer> players, int taskerRoleId, MmochatTask task,
			Integer npcId) {
		try {
			if (players == null || players.size() == 0 || task == null) {
				return null;
			}

			// 让队长站中间
			String name1 = "";
			try {
				for (MmochatPlayer me : players) {
					if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
						players.remove(me);
						players.add(0, me);
						name1 = me.getName();
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (players.size() > 1) {
				name1 += "(队)";
			}

			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);
			newBattle.setTaskBattle_taskId(task.getTaskId());
			newBattle.setTaskBattle_roleId(taskerRoleId);
			if (npcId != null) {
				newBattle.setTmpNpcId(npcId);
			}

			// 任务类型名和战斗类型名要一致
			newBattle.setType(MmochatBattleType.valueOf(task.getTaskType()
					.toString()));

			for (MmochatPlayer player : players) {
				player.stopDeal();
				if (player.lockState(MmochatRoleStateType.进入战斗时)) {
					if (!player.isInBattle() && player.getMapId() == mapId
							&& player.getLine() == line) {
						newBattle.addLeftTeam(player, false);
					}
					player.unLockState();
				} else {
					log.debug(player.getName() + "当前状态为:"
							+ player.getState().toString() + ",队伍的mapId="
							+ mapId + ", 此人的mapId=" + player.getMapId()
							+ ",无法进入战斗!");
				}
			}
			if (newBattle.getLeftTeam().size() == 0) {
				if (newBattle.getLeftTeam().size() == 0
						|| newBattle.getRightTeam().size() == 0) {
					newBattle.closeBattle();
					log.debug("一边队伍无人参战，NPC战斗无法进行。");
					return null;
				}
			}

			String name2 = "";
			MmochatMonsterFactory bossFactory = task.getFinish_need_battles()
					.getBoss();
			if (bossFactory != null) {
				MmochatMonster boss = ((MmochatMonster) bossFactory).getClone();
				newBattle.addRightTeam(boss, false);
				name2 = boss.getName();
			}

			for (MmochatMonsterFactory monsterFactory : task
					.getFinish_need_battles().getSmallBoss()) {
				if (monsterFactory != null) {
					MmochatMonster monster = ((MmochatMonster) monsterFactory)
							.getClone();
					newBattle.addRightTeam(monster, false);
					if (name2.length() == 0) {
						name2 = monster.getName();
					}
				}
			}

			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			for (MmochatRole player : players) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(newBattle.getType());
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role.getId());
						r.setBmpType(role.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role.getName();
							r.setName(name);
						} else {
							r.setName(role.getName());
						}
						r.setSmeValue(role.getSmeValue());
						r.setTotalBlood(role.getTotalBlood());
						r.setCurPkBlood(role.getCurPkBlood());
						r.setTotalSprit(role.getTotalSprit());
						r.setCurPkSprit(role.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
			return newBattle;
		} catch (Exception e) {
			e.printStackTrace();
			for (MmochatPlayer player : players) {
				player.unLockState();
			}
			return null;
		}
	}

	// 与NPC的战斗，并且直接使用MmochatMonsterFactory中的MmochatMonster参数作为怪物数据
	// NPC只有2个，并且位置居中
	public static MmochatBattle enterFamilyNpcPkWithMonsterData(int mapId,
			byte line, List<MmochatPlayer> players, int taskerRoleId,
			MmochatTask task, Integer npcId) {
		try {
			if (players == null || players.size() == 0 || task == null) {
				return null;
			}

			// 让队长站中间
			String name1 = "";
			try {
				for (MmochatPlayer me : players) {
					if (MmochatTeamService.getTeamState(me) != MmochatTeamStateType.队员) {
						players.remove(me);
						players.add(0, me);
						name1 = me.getName();
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (players.size() > 1) {
				name1 += "(队)";
			}
			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);
			newBattle.setTaskBattle_taskId(task.getTaskId());
			newBattle.setTaskBattle_roleId(taskerRoleId);
			if (npcId != null) {
				newBattle.setTmpNpcId(npcId);
			}

			// 任务类型名和战斗类型名要一致
			newBattle.setType(MmochatBattleType.valueOf(task.getTaskType()
					.toString()));

			for (MmochatPlayer player : players) {
				player.stopDeal();
				if (player.lockState(MmochatRoleStateType.进入战斗时)) {
					if (!player.isInBattle() && player.getMapId() == mapId
							&& player.getLine() == line) {
						newBattle.addLeftTeam(player, false);
					}
					player.unLockState();
				} else {
					log.debug(player.getName() + "当前状态为:"
							+ player.getState().toString() + ",队伍的mapId="
							+ mapId + ", 此人的mapId=" + player.getMapId()
							+ ",无法进入战斗!");
				}
			}
			if (newBattle.getLeftTeam().size() == 0) {
				if (newBattle.getLeftTeam().size() == 0
						|| newBattle.getRightTeam().size() == 0) {
					newBattle.closeBattle();
					log.debug("一边队伍无人参战，NPC战斗无法进行。");
					return null;
				}
			}

			String name2 = "";
			MmochatMonsterFactory bossFactory = task.getFinish_need_battles()
					.getBoss();
			if (bossFactory != null) {
				MmochatMonster boss = ((MmochatMonster) bossFactory).getClone();
				newBattle.addRightTeam(boss, false);
				name2 = boss.getName();
			}

			for (MmochatMonsterFactory monsterFactory : task
					.getFinish_need_battles().getSmallBoss()) {
				if (monsterFactory != null) {
					MmochatMonster monster = ((MmochatMonster) monsterFactory)
							.getClone();
					newBattle.addRightPetTeam(monster, false);
					if (name2.length() == 0) {
						name2 = monster.getName();
					}
				}
			}

			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			for (MmochatRole player : players) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) player;
					Byte myPos = newBattle.getPos(player);
					if (myPos != null) {
						pack.setMyPos(myPos);
						MmochatPet pet = me.getPetInBattle();
						if (pet != null) {
							Byte petPos = newBattle.getPos(pet);
							if (petPos != null) {
								pack.setPetPos(petPos);
							}
						}
						MmochatUtil.sendCommonPack(me, pack);
					}
				}
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(newBattle.getType());
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role.getId());
						r.setBmpType(role.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role.getName();
							r.setName(name);
						} else {
							r.setName(role.getName());
						}
						r.setSmeValue(role.getSmeValue());
						r.setTotalBlood(role.getTotalBlood());
						r.setCurPkBlood(role.getCurPkBlood());
						r.setTotalSprit(role.getTotalSprit());
						r.setCurPkSprit(role.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
			return newBattle;
		} catch (Exception e) {
			e.printStackTrace();
			for (MmochatPlayer player : players) {
				player.unLockState();
			}
			return null;
		}
	}

	// 锁妖塔战斗
	public static MmochatBattle enterTowerPk(int mapId, byte line,
			MmochatPlayer role, MmochatMonsterFactory bossFactory,
			MmochatMonsterFactory monsterFactory) {
		if (role == null) {
			return null;
		}

		try {
			MmochatBattle newBattle = new MmochatBattle();
			battles.put(newBattle.getBattleId(), newBattle);

			newBattle.setType(MmochatBattleType.锁妖塔战斗);

			role.stopDeal();
			if (role.lockState(MmochatRoleStateType.进入战斗时)) {
				if (!role.isInBattle() && role.getMapId() == mapId
						&& role.getLine() == line) {
					newBattle.addLeftTeam(role, false);
				}
				role.unLockState();
			} else {
				log.debug(role.getName() + "当前状态为:"
						+ role.getState().toString() + ",队伍的mapId=" + mapId
						+ ", 此人的mapId=" + role.getMapId() + ",无法进入战斗!");
			}

			if (newBattle.getLeftTeam().size() == 0) {
				if (newBattle.getLeftTeam().size() == 0
						|| newBattle.getRightTeam().size() == 0) {
					log.debug("一边队伍无人参战，NPC战斗无法进行。");
					newBattle.closeBattle();
					return null;
				}
			}

			MmochatMonster boss = MmochatEquipService
					.setMonsterBattleParam(bossFactory);
			newBattle.addRightTeam(boss, false);

			MmochatMonster monster = MmochatEquipService
					.setMonsterBattleParam(monsterFactory);
			newBattle.addRightPetTeam(monster, false);

			String name1 = role.getName();
			String name2 = boss.getName();

			// 下发进入战斗
			Mmochat_3_1S pack = new Mmochat_3_1S();
			pack.setBattle(newBattle);
			pack.setMapId(mapId);
			pack.setLine(line);
			MmochatPlayer me = (MmochatPlayer) role;
			Byte myPos = newBattle.getPos(role);
			if (myPos != null) {
				pack.setMyPos(myPos);
				MmochatPet pet = me.getPetInBattle();
				if (pet != null) {
					Byte petPos = newBattle.getPos(pet);
					if (petPos != null) {
						pack.setPetPos(petPos);
					}
				}
				MmochatUtil.sendCommonPack(me, pack);
			}

			// 战斗录像
			try {
				if (MmochatConstant.isBattleRecordOpen) {
					MmochatBattleRecord record = new MmochatBattleRecord();
					record.setType(newBattle.getType());
					record.setName1(name1);
					record.setName2(name2);
					record.setTurn(newBattle.getTurn());

					for (Entry<Byte, MmochatRole> entry : newBattle.getRoles()
							.entrySet()) {
						Byte pos = entry.getKey();
						MmochatRole role1 = entry.getValue();
						MmochatRoleRecord r = new MmochatRoleRecord();
						r.setId(role1.getId());
						r.setBmpType(role1.getBmpType());
						if (MmochatMain.serverType == MmochatServerType.跨服战服务器
								&& role1 instanceof MmochatPlayer) {
							MmochatPlayer p = (MmochatPlayer) role1;
							String name = "";
							if (p.getCurChenHao() != null) {
								name = p.getCurChenHao().getName() + "-";
							}
							name += role1.getName();
							r.setName(name);
						} else {
							r.setName(role1.getName());
						}
						r.setSmeValue(role1.getSmeValue());
						r.setTotalBlood(role1.getTotalBlood());
						r.setCurPkBlood(role1.getCurPkBlood());
						r.setTotalSprit(role1.getTotalSprit());
						r.setCurPkSprit(role1.getCurPkSprit());
						record.getRoles().put(pos, r);
					}
					tmpBattleRecords.put(newBattle.getBattleId(), record);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			newBattle.start();
			return newBattle;
		} catch (Exception e) {
			e.printStackTrace();
			role.unLockState();
			return null;
		}
	}

	// 帮派副本战斗
	public static String enterGangModelBattle(MmochatPlayer me, MmochatNpc npc,
			MmochatBattleModelType modelType, MmochatTaskType taskType) {
		List<MmochatPlayer> members = new ArrayList<MmochatPlayer>();
		if (me.isInTeam()) {
			MmochatTeam team = MmochatTeamService.teams.get(me.getTeamId());
			if (team == null) {
				me.leaveTeam();
				members.add(me);
			} else {
				for (Integer roleId : team.getMemberId().values()) {
					MmochatPlayer member = MmochatMainService
							.getRoleFromBuffer(roleId);
					if (member != null) {
						members.add(member);
					}
				}
			}
		} else {
			members.add(me);
		}

		MmochatGang gang = MmochatGangService.getGangById(me.getGangId());
		// 帮贡500以上才能参加战斗
		if (gang != null) {
			for (MmochatPlayer member : members) {
				MmochatGangMember info = gang.getMembers().get(
						member.getRoleId());
				if (info != null) {
					if (info.getBuildValue() < 500) {
						return MmochatUtil.wrapColor(member.getName(),
								Color.green)
								+ "的帮派贡献度未达到500点，不能参加帮派副本!";
					}
				}
			}
		}

		MmochatNpcBattle battle = MmochatMainService
				.getBattleModelByType(modelType);
		if (battle == null) {
			return "战斗异常，请联系客服";
		}
		MmochatTask task = new MmochatTask();
		task.setTaskType(taskType);
		task.setFinish_need_battles(battle);

		// 进入战斗
		MmochatTempNpc activeNpc = (MmochatTempNpc) npc;
		synchronized (activeNpc) {
			if (activeNpc.getState() == MmochatNpcState.空闲) {
				activeNpc.setState(MmochatNpcState.战斗中);
			} else if (activeNpc.getState() == MmochatNpcState.离开) {
				return "目标已经离开!";
			} else if (activeNpc.getState() == MmochatNpcState.战斗中) {
				return "目标正在战斗中,请稍候再来!";
			}
		}
		MmochatBattleService.enterNpcPk(me.getMapId(), (byte) me.getLine(),
				members, me.getRoleId(), task, npc.getNpcId());
		return null;
	}

	public static SkymobiProtocolMessage dealUploadAction(MmochatAction action) {
		if (action == null) {
			return null;
		}
		log.debug("上传战斗操作");
		MmochatBattle battle = battles.get(action.getBattleId());
		if (battle == null || battle.isOver()) {
			// 战斗不存在或已经结束,下发结束战斗
			MmochatBattle endBattle = new MmochatBattle();
			endBattle.setBattleId(action.getBattleId());
			endBattle.setTurn(action.getTurn() + 1);
			endBattle.setOver();
			Mmochat_3_3S pack = new Mmochat_3_3S();
			pack.setBattle(endBattle);
			return pack;
		}
		if (action.getTurn() != battle.getTurn()) {
			// 回合数不对应,过滤此操作
			log.debug("操作的回合数不对，过滤此操作");
			return null;
		}
		if (battle.getState() == MmochatBattleState.所有玩家操作完毕) {
			if (battle.getActions().size() != battle.getRoles().size()) {
				// 有玩家未操作完成
				battle.setState(MmochatBattleState.战斗新回合玩家操作中);
			} else {
				// 已经准备完毕,不再接收操作
				log.debug("所有玩家操作完毕，过滤此操作");
				return null;
			}
		}
		MmochatRole role = battle.getRoles().get(action.getPos());
		if (role == null) {
			// 角色不存在
			log.debug("角色不存在，过滤此操作");
			return null;
		}
		action.setRole(role);

		if (battle.getActions().size() + 1 != battle.getRoles().size()) {
			// 人宠是否都已经完成操作
			byte rolePos = 0;
			boolean optionDone = false;
			if (role instanceof MmochatPet) {
				// 本次是宠物操作；
				optionDone = true;
				rolePos = MmochatBattle.getManPos(action.getPos());
			} else if (role instanceof MmochatPlayer) {
				byte petPos = MmochatBattle.getPetPos(action.getPos());
				if (battle.getRoles().get(petPos) == null) {
					// 本次是人物操作，人不带宠
					optionDone = true;
					rolePos = action.getPos();
				}
			}
			if (optionDone) {
				// 下发完成操作，闹钟消失
				Mmochat_3_4S pack = new Mmochat_3_4S();
				pack.setPos(rolePos);
				MmochatRole myRole = battle.getRoles().get(rolePos);
				for (MmochatRole player : battle.getRoles().values()) {
					if (player == myRole) {
						continue;
					}
					if (player instanceof MmochatPlayer) {
						MmochatPlayer p = (MmochatPlayer) player;
						if (p.isDeadConnection()) {
							continue;
						}
						p.setLastActionTime();
						MmochatUtil.sendCommonPack(p, pack);
					}
				}

				// 向观战者下发
				for (MmochatPlayer p : battle.getAudiences().values()) {
					if (p.isDeadConnection()) {
						continue;
					}
					p.setLastActionTime();
					MmochatUtil.sendCommonPack(p, pack);
				}

				// 战斗录像
				try {
					MmochatBattleRecord record = tmpBattleRecords.get(battle
							.getBattleId());
					if (record != null) {
						MmochatBattleActionClockRecord clock = new MmochatBattleActionClockRecord();
						clock.setPos(rolePos);
						record.getClocks().add(clock);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		battle.addAction(action);
		checkBattleIsReady(battle);
		return null;
	}

	// 上传战斗操作
	@SkymobiService
	public SkymobiProtocolMessage handleC_3_2(SkymobiHandler handler,
			Mmochat_3_2C req) {
		log.debug("收到上传战斗消息!");
		MmochatAction action = req.getAction();
		if (action == null) {
			return null;
		}
		return dealUploadAction(action);
	}

	// 请求可召唤宠物列表
	@SkymobiService
	public SkymobiProtocolMessage handleC_3_6(SkymobiHandler handler,
			Mmochat_3_6C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		List<MmochatPet> petList = new ArrayList<MmochatPet>();
		if (me != null) {
			if (!me.isInBattle() || me.getBattleId() != req.getBattleId()) {
				return null;
			}

			for (MmochatPet pet : me.getPets().values()) {
				if (!pet.isInPk() && !pet.isHasUsedInPk()) {
					if (pet.getLevel() > me.getLevel()
							+ MmochatConstant.maxPetLevelMoreThanOwner) {
						continue;
					}
					if (pet.getLife_turn() > me.getLife_turn()) {
						continue;
					}
					if (pet.getCurPkBlood() > 0 && !pet.isHasUsedInPk()) {
						petList.add(pet);
					}
				}
			}
		}
		if (petList.size() == 0) {
			// 没有可参战的宠物
			CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
			msgbox.setContent(new Text("没有可参战的宠物!已经出战过的宠物在本场战斗中不能再被召唤。"));
			msgbox.setLeftName("确定");
			msgbox.addLeftTLV(new CallLocalFuncTlv(
					MmochatConstant.funcode_pkFunc,
					MmochatConstant.subcode_showManPanel, 0));
			return MmochatUtil.tlvResponse(req.getHallState(), msgbox);
		}

		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.List);
		if (petList.size() > 0) {
			tlv.setLeftName("出战");
		}
		tlv.setRightName("返回");
		tlv.setTitle("可参战宠物");
		tlv.setWinHeight(188);
		tlv.setWinId(MmochatConstant.TLV_WIN_PKCALLPET);
		tlv.addRightTLV(new CallLocalFuncTlv(MmochatConstant.funcode_pkFunc,
				MmochatConstant.subcode_showManPanel,
				MmochatConstant.TLV_WIN_PKCALLPET));

		for (MmochatPet pet : petList) {
			String item = pet.getName();
			if (pet.getState() == MmochatPetStateType.替补) {
				item += "(替补)";
			}
			tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV((int) pet
					.getPetId()));
		}
		if (petList.size() > 0) {
			tlv.addLeftTLV(new AddDataTLV((int) req.getBattleId()));
			tlv.addLeftTLV(new AddDataTLV((int) req.getTurn()));
			tlv.addLeftTLV(new AddDataTLV((int) req.getPos()));
			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_3_7, null));
			tlv.addLeftTLV(new CallLocalFuncTlv(MmochatConstant.funcode_pkFunc,
					MmochatConstant.subcode_showPetPanel,
					MmochatConstant.TLV_WIN_PKCALLPET));
		}
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 上传召唤宠物操作
	@SkymobiService
	public SkymobiProtocolMessage handleC_3_7(SkymobiHandler handler,
			Mmochat_3_7C req) {
		MmochatAction action = req.getAction();
		if (action == null) {
			return null;
		}

		return dealUploadAction(action);
	}

	// 上传战斗结束，退出战场
	@SkymobiService
	public void handleC_3_8(SkymobiHandler handler, Mmochat_3_8C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return;
		}
		// MmochatMainService.dealDead(me);
	}

	// 上传战斗心跳包，防止卡在战斗中
	@SkymobiService
	public SkymobiProtocolMessage handleC_3_14(SkymobiHandler handler,
			Mmochat_3_14C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return null;
		}

		if (!me.isInBattle()) {
			// TODO: 如果我已经不在战斗中了，收到这个心跳包时，表示终端仍在战斗界面，则再次下发告诉终端退出战斗
			// 战斗不存在或已经结束,下发结束战斗
			MmochatBattle endBattle = new MmochatBattle();
			endBattle.setBattleId(req.getBattleId());
			endBattle.setTurn(req.getTurn() + 1);
			endBattle.setOver();
			Mmochat_3_3S pack = new Mmochat_3_3S();
			pack.setBattle(endBattle);
			return pack;
		}
		return null;
	}

	// 所有人操作完毕,下发操作
	public static void checkBattleIsReady(MmochatBattle battle) {
		try {
			if (battle.getState() == MmochatBattleState.战斗即将结束
					|| battle.getState() == MmochatBattleState.战斗结束) {
				return;
			}

			if (battle.getActions().size() < battle.getRoles().size()) {
				return;
			}

			synchronized (battle) {
				if (battle.getActions().size() < battle.getRoles().size()) {
					return;
				}
				if (battle.getState() == MmochatBattleState.所有玩家操作完毕) {
					return;
				}
				battle.setState(MmochatBattleState.所有玩家操作完毕);
			}

			log.debug("所有玩家操作完毕，下发动画");

			// 所有人都操作完毕,下发动画序列
			battle = generateRoundFrame(battle);
			battle.setActionPlayTimePerRound(battle.getFrames().size());
			boolean maxRoundOver = false;
			if (battle.isTouchRoundMax()) {
				// 超过最大回合数，强制结束战斗
				battle.dealTouchRoundMax();
				if (!battle.isOver()) {
					battle.setOver();
					maxRoundOver = true;
				}
			}

			MmochatBattle cloneBattle = battle;
			try {
				synchronized (battle) {
					cloneBattle = battle.getClone();
				}
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			for (MmochatRole player : battle.getRoles().values()) {
				if (player instanceof MmochatPlayer) {
					MmochatPlayer p = (MmochatPlayer) player;
					if (p.isDeadConnection()) {
						continue;
					}
					p.setLastActionTime();

					Integer petId = null;
					MmochatPet pet = p.getPetInBattle();
					if (pet != null) {
						petId = pet.getId();
					}
					SendBigPackUtil.sendBigPack_pkAction(p, cloneBattle, petId);

					if (maxRoundOver) {
						MmochatChatService.sendSystemMsgToPerson(p,
								"战斗回合超过最大回合数，系统强制结束战斗");
					}
				}
			}

			// 向观战者下发
			for (MmochatPlayer p : battle.getAudiences().values()) {
				p.setLastActionTime();
				SendBigPackUtil.sendBigPack_pkAction(p, cloneBattle, null);

				if (maxRoundOver) {
					MmochatChatService.sendSystemMsgToPerson(p,
							"战斗回合超过最大回合数，系统强制结束战斗");
				}
			}

			// 战斗录像
			try {
				MmochatBattleRecord record = tmpBattleRecords.get(battle
						.getBattleId());
				if (record != null) {
					MmochatBattleRoundRecord roundRecord = new MmochatBattleRoundRecord();
					roundRecord.setBattleId(record.getId());
					roundRecord.setTurn(cloneBattle.getTurn());
					roundRecord.setRoundNewStates(cloneBattle
							.getRoundNewStates());
					roundRecord.setNewRoles_delRole(cloneBattle
							.getNewRoles_delRole());
					roundRecord.setNewRoles_addRole(cloneBattle
							.getNewRoles_addRole());
					roundRecord.setNewRoles_changeState(cloneBattle
							.getNewRoles_changeState());
					roundRecord.setFrames(cloneBattle.getFrames());
					roundRecord.setOver(cloneBattle.isOver());
					record.getRounds().add(roundRecord);

					if (cloneBattle.isOver()) {
						// 战斗结束，录制完成
						if (record.isSave()) {
							Collections.sort(record.getRounds());
							battleRecords.put(record.getId(), record);
						}
						tmpBattleRecords.remove(battle.getBattleId());
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			if (battle.isOver()) {
				// 战斗结束的处理
				if (maxRoundOver) {
					battle.closeBattle();
				} else {
					battle.setState(MmochatBattleState.战斗即将结束);
				}
				// try {
				// if (!maxRoundOver) {
				// battle.handleAward();
				// }
				// } catch (Exception e) {
				// e.printStackTrace();
				// } finally {
				// battle.closeBattle();
				// }
				return;
			}

			// 初始化新回合，接受新回合的操作
			battle.addTurn();
			battle.initNewRound();

			battle.setState(MmochatBattleState.战斗动画播放中);
			log.debug("战斗动画播放中");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 上传战斗动画播放结束
	@SkymobiService
	public void handleC_3_10(SkymobiHandler handler, Mmochat_3_10C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return;
		}

		MmochatBattle battle = battles.get(req.getBattleId());
		if (battle == null || battle.isOver()
				|| battle.getState() != MmochatBattleState.战斗动画播放中) {
			return;
		}
		if (battle.getTurn() - 1 != req.getTurn()) {
			return;
		}
		log.debug("上传战斗动画播放结束");
		battle.getAniOverMap().put(me.getRoleId(), me.getRoleId());
		battle.setAniOverForOfflinePlayer();

		// 所有人的动画播放结束，进入到新回合
		if (battle.isAllAniOver()) {
			synchronized (battle) {
				if (battle.getState() != MmochatBattleState.战斗动画播放中) {
					return;
				}
				battle.setState(MmochatBattleState.战斗新回合玩家操作中);
			}
			// 给所有离线玩家和怪物添加自动战斗
			battle.addActionForOfflinePlayerAndMonster();
			checkBattleIsReady(battle);
		}
	}

	// 返回实际操作目标;非冰冻优先，速度优先(较大波动),适合：法术技能
	private static List<MmochatRole> getTargetRoleListBySpeedNoFreezeBigWave(
			MmochatBattle battle, Byte targetPos, int targetNum) {
		Comparator<MmochatRole> comp = new Comparator<MmochatRole>() {
			public int compare(MmochatRole p1, MmochatRole p2) {
				// 返回值大于0，则第一个传参(p1)排在后面；否则第一个传参排在前面
				int randSpeed = MmochatUtil.getRandomValue(301);
				int mySpeed = p1.getSpeed() - 150 + randSpeed;
				int p1Value = -1 * mySpeed;
				if (p1.hasSme(MmochatSmeType.冰冻)) {
					p1Value += 100000000;
				}

				randSpeed = MmochatUtil.getRandomValue(301);
				mySpeed = p2.getSpeed() - 150 + randSpeed;
				int p2Value = -1 * mySpeed;
				if (p2.hasSme(MmochatSmeType.冰冻)) {
					p2Value += 100000000;
				}
				if (p1Value > p2Value)
					return 1;
				else
					return 0;
			}
		};
		return getTargetRoleListEx(battle, targetPos, targetNum, comp);
	}

	// 返回实际操作目标;速度优先(0波动),适合：冰冻障碍技能
	private static List<MmochatRole> getTargetRoleListBySpeedNoWave(
			MmochatBattle battle, Byte targetPos, int targetNum) {
		Comparator<MmochatRole> comp = new Comparator<MmochatRole>() {
			public int compare(MmochatRole p1, MmochatRole p2) {
				// 返回值大于0，则第一个传参(p1)排在后面；否则第一个传参排在前面
				int p1Value = -1 * p1.getSpeed();
				int p2Value = -1 * p2.getSpeed();
				if (p1Value > p2Value)
					return 1;
				else
					return 0;
			}
		};
		return getTargetRoleListEx(battle, targetPos, targetNum, comp);
	}

	// 返回实际操作目标;非冰冻优先，速度优先(0波动)，适合：非冰冻障碍技能，加速辅助，加防辅助
	private static List<MmochatRole> getTargetRoleListBySpeedNoFreezeNoWave(
			MmochatBattle battle, Byte targetPos, int targetNum) {
		Comparator<MmochatRole> comp = new Comparator<MmochatRole>() {
			public int compare(MmochatRole p1, MmochatRole p2) {
				// 返回值大于0，则第一个传参(p1)排在后面；否则第一个传参排在前面
				int p1Value = -1 * p1.getSpeed();
				if (p1.hasSme(MmochatSmeType.冰冻)) {
					p1Value += 100000000;
				}

				int p2Value = -1 * p2.getSpeed();
				if (p2.hasSme(MmochatSmeType.冰冻)) {
					p2Value += 100000000;
				}
				if (p1Value > p2Value)
					return 1;
				else
					return 0;
			}
		};
		return getTargetRoleListEx(battle, targetPos, targetNum, comp);
	}

	// 返回实际操作目标;非冰冻优先，伤害优先(0波动)，适合：加攻辅助
	private static List<MmochatRole> getTargetRoleListByAttack(
			MmochatBattle battle, Byte targetPos, int targetNum) {
		Comparator<MmochatRole> comp = new Comparator<MmochatRole>() {
			public int compare(MmochatRole p1, MmochatRole p2) {
				// 返回值大于0，则第一个传参(p1)排在后面；否则第一个传参排在前面
				int tmpV1, tmpV2;
				tmpV1 = p1.getPhysicalAttack();
				tmpV2 = p1.getSpritAttack();
				int p1Value = tmpV1 > tmpV2 ? tmpV1 : tmpV2;
				p1Value = -1 * p1Value;
				if (p1.hasSme(MmochatSmeType.冰冻)) {
					p1Value += 100000000;
				}

				tmpV1 = p2.getPhysicalAttack();
				tmpV2 = p2.getSpritAttack();
				int p2Value = tmpV1 > tmpV2 ? tmpV1 : tmpV2;
				p2Value = -1 * p2Value;
				if (p2.hasSme(MmochatSmeType.冰冻)) {
					p2Value += 100000000;
				}
				if (p1Value > p2Value)
					return 1;
				else
					return 0;
			}
		};
		return getTargetRoleListEx(battle, targetPos, targetNum, comp);
	}

	/*
	 * 法攻：非冰冻优先，速度优先(较大波动)
	 * 
	 * 障碍： 1、冰冻：速度优先(0波动) 2、其它：非冰冻优先，速度优先(0波动)
	 * 
	 * 辅助： 1、加速：非冰冻优先，速度优先(0波动) 2、加防：非冰冻优先，速度优先(0波动) 3、加攻：非冰冻优先，伤害优先(0波动)
	 */
	/*
	 * 返回实际操作目标;按指定的方式排序选取非主选目标; comp:排序方式
	 */
	private static List<MmochatRole> getTargetRoleListEx(MmochatBattle battle,
			Byte targetPos, int targetNum, Comparator<MmochatRole> comp) {
		List<MmochatRole> targetList = new ArrayList<MmochatRole>();
		if (battle == null || targetPos == null || targetNum <= 0
				|| comp == null) {
			return targetList;
		}
		MmochatRole target = battle.getRoles().get(targetPos);
		int restTargetNum = targetNum;
		if (target != null && target.getCurPkBlood() > 0) {
			// 原目标有效
			targetList.add(target);
			restTargetNum--;
		}
		if (restTargetNum <= 0) {
			return targetList;
		}

		// 从活着的其它目标中选取
		Map<Byte, MmochatRole> myAliveTeamers = battle
				.getMyAliveTeamersExceptMe(targetPos);
		List<MmochatRole> myTeamerList = new ArrayList<MmochatRole>(
				myAliveTeamers.values());

		Collections.sort(myTeamerList, comp);

		int curTargetNum = Math.min(restTargetNum, myTeamerList.size());
		// restTargetNum -= curTargetNum;
		for (int i = 0; i < curTargetNum; i++) {
			try {
				MmochatRole curTarget = myTeamerList.get(i);
				targetList.add(curTarget);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return targetList;
	}

	/*
	 * 获取横扫千军的附加目标:主目标横向最近的1个目标
	 */
	private static List<MmochatRole> getExtraTargetListOf横扫千军(
			MmochatBattle battle, Byte mainTargetPos) {
		List<MmochatRole> targetList = new ArrayList<MmochatRole>();
		if (battle == null || mainTargetPos == null) {
			return targetList;
		}

		int startPos = mainTargetPos / 5 * 5;
		int endPos = startPos + 4;
		// 从相邻距离1-4
		for (int dist = 1; dist <= 4; dist++) {
			// 左位
			int pos = mainTargetPos - dist;
			if (pos >= startPos) {
				MmochatRole target = battle.getRoles().get((byte) pos);
				if (target != null && target.getCurPkBlood() > 0) {
					targetList.add(target);
					break;
				}
			}
			// 右位
			pos = mainTargetPos + dist;
			if (pos <= endPos) {
				MmochatRole target = battle.getRoles().get((byte) pos);
				if (target != null && target.getCurPkBlood() > 0) {
					targetList.add(target);
					break;
				}
			}
		}
		return targetList;
	}

	// 获得对方队伍中使用了特定指令的玩家
	private static List<MmochatRole> getEnermyWithBattleOrder(
			MmochatBattle battle, Byte myPos, MmochatBattleOrderType order) {
		List<MmochatRole> targetList = new ArrayList<MmochatRole>();
		if (battle == null || myPos == null) {
			return targetList;
		}

		List<MmochatRole> teamerList = new ArrayList<MmochatRole>();
		Map<Byte, MmochatRole> teamers = battle.getTheOtherAliveTeamers(myPos);
		for (MmochatRole role : teamers.values()) {
			if (role.hasBattleOrder(order)) {
				teamerList.add(role);
			}
		}
		return teamerList;
	}

	// 角色图片变更
	private static MmochatRoundFrame resetRole(MmochatRoundFrame frame,
			byte targetPos, MmochatRole targetRole) {
		// 重置形象
		targetRole.resetCurRoleBmpType();
		frame.addNewRoleState_delRole(targetPos, targetRole);
		frame.addNewRoleState_addRole(targetPos, targetRole);
		return frame;
	}

	// 处理死亡
	private static void dealBattleRoleDie(MmochatBattle battle,
			MmochatRoundFrame frame, byte diePos, MmochatRole dieRole) {
		frame.addNewRoleState_delRole(diePos, dieRole);
		if (!dieRole.isCanRescure()) {
			battle.delRole(diePos, true);
		}

		if (dieRole instanceof MmochatPet) {
			// 如果是参战宠物死亡，则替补宠物上场
			MmochatPet diePet = (MmochatPet) dieRole;
			diePet.setInPk(false);
			byte manPos = MmochatBattle.getManPos(diePos);
			MmochatRole myRole = battle.getRoles().get(manPos);
			if (myRole != null && myRole instanceof MmochatPlayer) {
				MmochatPlayer me = (MmochatPlayer) myRole;
				MmochatPet bakPet = me.getBakPkPet();
				if (bakPet != null && bakPet.getId() != dieRole.getId()
						&& !bakPet.isHasUsedInPk()
						&& bakPet.getCurPkBlood() > 0) {
					// 如果有替补宠，且死亡宠不是此替补宠，且替补宠未出战过，则替补宠自动出战
					bakPet.setHasUsedInPk(true);
					bakPet.setInPk(true);
					// 增加到战场中
					frame.addNewRoleState_addRole(diePos, bakPet, "替补宠");
					battle.addRole(diePos, bakPet);
				}
			}
		}
	}

	// 生成回合frame
	@SuppressWarnings("unused")
	private static MmochatBattle generateRoundFrame(MmochatBattle battle) {
		if (battle == null || battle.getActions().size() == 0) {
			return battle;
		}
		battle.getFrames().clear();
		List<MmochatAction> actionList = new ArrayList<MmochatAction>(battle
				.getActions().values());

		// TODO:回合操作前状态改变的角色:roundNewStates

		// 第一轮，对防御等进行预设置
		for (MmochatAction action : actionList) {
			if (action.getActionType() == MmochatActionType.防御) {
				MmochatRole myRole = battle.getRoles().get(action.getPos());
				if (myRole == null) {
					continue;
				}
				myRole.setUseDefendInPk(true);
			}
		}

		while (!actionList.isEmpty()) {
			// 按速度排序、未被障碍的丹药使用者优于普通操作
			Collections.sort(actionList);

			MmochatAction action = null;
			try {
				action = actionList.remove(0);
			} catch (Exception e) {
				e.printStackTrace();
				break;
			}

			MmochatRoundFrame frame = new MmochatRoundFrame();
			frame.setPos(action.getPos());
			frame.setActionType(action.getActionType());

			// 是否一方全灭
			if (battle.canBattleBeOver()) {
				battle.setOver();
				// 后面其它人的操作不再执行
				return battle;
			}

			MmochatRole myRole = battle.getRoles().get(action.getPos());
			if (myRole == null) {
				// 可能已经被杀或召回
				continue;
			}

			if ((battle.getType() == MmochatBattleType.友好切磋
					|| battle.getType() == MmochatBattleType.强制杀戮
					|| battle.getType() == MmochatBattleType.锁妖塔战斗 || battle
					.getType() == MmochatBattleType.跨服武道会比赛)
					&& action.getActionType() == MmochatActionType.逃跑) {
				// 如果是切磋，则逃跑必然成功
			} else {
				// 异常状态处理
				if (myRole.hasSme(MmochatSmeType.死亡)) {
					continue;
				} else if (myRole.hasSme(MmochatSmeType.冰冻)) {
					continue;
				} else if (myRole.hasSme(MmochatSmeType.混乱)) {
					// 混乱后对本方和敌方物攻的机率设置
					Map<Byte, MmochatRole> myTeamer = battle
							.getMyAliveTeamersExceptMe(action.getPos());
					MmochatRole targetRole;
					if (MmochatUtil.isInPercent(70) && myTeamer.size() > 0) {
						// 攻击本方
						List<MmochatRole> teamer = new ArrayList<MmochatRole>(
								myTeamer.values());
						int index = (int) (Math.random() * teamer.size());
						targetRole = teamer.get(index);
					} else {
						// 攻击敌方
						Map<Byte, MmochatRole> theOtherTeamer = battle
								.getTheOtherAliveTeamers(action.getPos());
						List<MmochatRole> teamer = new ArrayList<MmochatRole>(
								theOtherTeamer.values());
						int index = (int) (Math.random() * teamer.size());
						targetRole = teamer.get(index);
					}
					if (targetRole == null) {
						continue;
					}

					Byte targetPos = battle.getPos(targetRole);

					boolean isFreeze = targetRole.hasSme(MmochatSmeType.冰冻);
					boolean hit;
					if (isFreeze) {
						hit = true;
					} else {
						hit = calHit(myRole, targetRole, 0);
					}
					frame.addTarget(targetPos, hit);
					if (hit) {
						int[] attackValues = calPhysicalHurt(myRole, targetRole);
						targetRole.delCurPkBlood(attackValues[0]);
						boolean reset = false;
						if (attackValues[1] == 1) {
							reset = true;
						}
						if (targetRole.getCurPkBlood() <= 0) {
							if (!targetRole.isDisappearWhenDie()) {
								MmochatSme sme = new MmochatSme(
										MmochatSmeType.死亡, 1000);
								targetRole.addSme(sme);
								if (!reset) {
									frame.addNewRoleState_changeState(
											targetPos, targetRole);
								} else {
									// 重置形象
									frame = resetRole(frame, targetPos,
											targetRole);
								}
								if (!targetRole.isCanRescure()) {
									battle.delRole(targetPos, true);
								}
							} else {
								// 死后消失
								dealBattleRoleDie(battle, frame, targetPos,
										targetRole);
							}
						} else {
							if (!reset) {
								frame.addNewRoleState_changeState(targetPos,
										targetRole);
							} else {
								// 重置形象
								frame = resetRole(frame, targetPos, targetRole);
							}
						}
					}

					frame.setActionType(MmochatActionType.物攻);
					battle.addFrame(frame);

					// 是否一方全灭
					if (battle.canBattleBeOver()) {
						battle.setOver();
						// 后面其它人的操作不再执行
						return battle;
					}
					continue;
				} else if (myRole.hasSme(MmochatSmeType.封印)) {
					// 封印后物攻的机率设置
					if (MmochatUtil.isInPercent(10)) {
						// 一定机率物攻敌方
						Map<Byte, MmochatRole> theOtherTeamer = battle
								.getTheOtherAliveTeamers(action.getPos());
						MmochatRole oldTarget = theOtherTeamer
								.get((Byte) action.getTargetPos());
						MmochatRole targetRole;
						if (oldTarget != null && oldTarget.getCurPkBlood() > 0) {
							targetRole = oldTarget;
						} else {
							List<MmochatRole> teamer = new ArrayList<MmochatRole>(
									theOtherTeamer.values());
							int index = (int) (Math.random() * teamer.size());
							targetRole = teamer.get(index);
						}
						if (targetRole != null) {
							Byte targetPos = battle.getPos(targetRole);
							boolean hit = calHit(myRole, targetRole, 0);
							frame.addTarget(targetPos, hit);
							if (hit) {
								int[] attackValues = calPhysicalHurt(myRole,
										targetRole);
								targetRole.delCurPkBlood(attackValues[0]);
								if (targetRole.getCurPkBlood() <= 0) {
									if (!targetRole.isDisappearWhenDie()) {
										MmochatSme sme = new MmochatSme(
												MmochatSmeType.死亡, 1000);
										targetRole.addSme(sme);
										if (attackValues[1] == 1) {
											// 重置形象
											frame = resetRole(frame, targetPos,
													targetRole);
										} else {
											frame.addNewRoleState_changeState(
													targetPos, targetRole);
										}
										if (!targetRole.isCanRescure()) {
											battle.delRole(targetPos, true);
										}
									} else {
										// 死后消失
										dealBattleRoleDie(battle, frame,
												targetPos, targetRole);
									}
								} else {
									if (attackValues[1] == 1) {
										// 重置形象
										frame = resetRole(frame, targetPos,
												targetRole);
									} else {
										frame.addNewRoleState_changeState(
												targetPos, targetRole);
									}
								}
							}
						}
						frame.setActionType(MmochatActionType.物攻);
						battle.addFrame(frame);

						// 是否一方全灭
						if (battle.canBattleBeOver()) {
							battle.setOver();
							// 后面其它人的操作不再执行
							return battle;
						}
						continue;
					} else {
						continue;
					}
				}
			}

			switch (action.getActionType()) {
			case NPC补血: {
				MmochatRole targetRole = battle.getRoles().get(
						action.getTargetPos());
				if (targetRole == null) {
					continue;
				}
				frame.addTarget(action.getTargetPos(), true);
				int addBlood = action.getAddBlood();
				if (addBlood > 0) {
					// 加血
					if (targetRole.hasSme(MmochatSmeType.死亡)) {
						if (!targetRole.isCanRescure()) {
							break;
						}
					}
					targetRole.delCurPkBlood(-1 * addBlood);
					if (targetRole.getCurPkBlood() > 0) {
						targetRole.delSme(MmochatSmeType.死亡);
					}
					frame.addNewRoleState_changeState(action.getTargetPos(),
							targetRole);
					frame.setActionType(MmochatActionType.加血);
				}
				break;
			}
			case 自动:
				break;
			case 物攻: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法进行物攻!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法进行物攻!");
					break;
				}
				MmochatRole mainTarget = battle.getRoles().get(
						action.getTargetPos());
				if (mainTarget == null || mainTarget.getCurPkBlood() <= 0) {
					// 原目标不存在或已死亡，选择其它目标
					Map<Byte, MmochatRole> theOtherTeamer = battle
							.getTheOtherAliveTeamers(action.getPos());
					List<MmochatRole> teamer = new ArrayList<MmochatRole>(
							theOtherTeamer.values());
					int index = (int) (Math.random() * teamer.size());
					mainTarget = teamer.get(index);
				}
				if (mainTarget == null) {
					continue;
				}

				Byte mainTargetPos = battle.getPos(mainTarget);
				// 主目标
				{
					boolean isFreeze = mainTarget.hasSme(MmochatSmeType.冰冻);
					boolean hit;
					if (isFreeze) {
						hit = true;
					} else {
						hit = calHit(myRole, mainTarget, 0);
					}
					frame.addTarget(mainTargetPos, hit);
					if (hit) {
						int[] attackValues = calPhysicalHurt(myRole, mainTarget);
						mainTarget.delCurPkBlood(attackValues[0]);
						if (mainTarget.getCurPkBlood() <= 0) {
							if (!mainTarget.isDisappearWhenDie()) {
								MmochatSme sme = new MmochatSme(
										MmochatSmeType.死亡, 1000);
								mainTarget.addSme(sme);
								if (attackValues[1] == 1) {
									// 重置形象
									frame = resetRole(frame, mainTargetPos,
											mainTarget);
								} else {
									frame.addNewRoleState_changeState(
											mainTargetPos, mainTarget);
								}
								if (!mainTarget.isCanRescure()) {
									battle.delRole(mainTargetPos, true);
								}
							} else {
								// 死后消失
								dealBattleRoleDie(battle, frame, mainTargetPos,
										mainTarget);
							}
						} else {
							if (attackValues[1] == 1) {
								// 重置形象
								frame = resetRole(frame, mainTargetPos,
										mainTarget);
							} else {
								frame.addNewRoleState_changeState(
										mainTargetPos, mainTarget);
							}
						}
					}
				}

				// 附加目标
				if (myRole instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) myRole;
					// 横扫千军
					MmochatSpecialSkill specialSkill = me
							.getSpecialSkill(MmochatSpecialSkillType.横扫千军);
					if (specialSkill != null
							&& specialSkill.getLevel() > 0
							&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
									.getEffectKey())) {
						double skillRate = MmochatSpecialSkillType
								.getAttackRateOf横扫千军(specialSkill.getLevel(),
										specialSkill.getProficiency());
						if (MmochatUtil.isInPercent(skillRate)) {
							// 触发
							double hurtParam = MmochatSpecialSkillType
									.getAttackParamOf横扫千军(specialSkill
											.getLevel());// 0.1-0.3

							List<MmochatRole> targetList = getExtraTargetListOf横扫千军(
									battle, mainTargetPos);
							for (MmochatRole targetRole : targetList) {
								if (targetRole == null
										|| targetRole.getCurPkBlood() <= 0) {
									// 原目标不存在或已死亡
									continue;
								}

								boolean isFreeze = targetRole
										.hasSme(MmochatSmeType.冰冻);
								Byte targetPos = battle.getPos(targetRole);
								boolean hit;
								if (isFreeze) {
									hit = true;
								} else {
									hit = calHit(myRole, targetRole, 0);
								}
								frame.addTarget(targetPos, hit);
								if (hit) {
									int[] attackValues = calPhysicalHurt(
											myRole, targetRole, hurtParam);
									targetRole.delCurPkBlood(attackValues[0]);
									if (targetRole.getCurPkBlood() <= 0) {
										if (!targetRole.isDisappearWhenDie()) {
											MmochatSme sme = new MmochatSme(
													MmochatSmeType.死亡, 1000);
											targetRole.addSme(sme);
											if (attackValues[1] == 1) {
												// 重置形象
												frame = resetRole(frame,
														targetPos, targetRole);
											} else {
												frame
														.addNewRoleState_changeState(
																targetPos,
																targetRole);
											}
											if (!targetRole.isCanRescure()) {
												battle.delRole(targetPos, true);
											}
										} else {
											// 死后消失
											dealBattleRoleDie(battle, frame,
													targetPos, targetRole);
										}
									} else {
										if (attackValues[1] == 1) {
											// 重置形象
											frame = resetRole(frame, targetPos,
													targetRole);
										} else {
											frame.addNewRoleState_changeState(
													targetPos, targetRole);
										}
									}
								}
							}
						}
					}
				}
				break;
			}
			case 道具: {
				// 如果道具被使用后, 需要更新此玩家终端的道具列表.
				// 于是要将此玩家加到到rolesNeedUpdateProp中.
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法使用道具!");
					break;
				}
				MmochatRole targetRole = battle.getRoles().get(
						action.getTargetPos());
				if (targetRole == null) {
					continue;
				}
				MmochatPlayer owner = null;
				if (myRole instanceof MmochatPlayer) {
					owner = (MmochatPlayer) myRole;
				} else if (myRole instanceof MmochatPet) {
					MmochatPet pet = (MmochatPet) myRole;
					for (MmochatRole role : battle.getRoles().values()) {
						if (role instanceof MmochatPlayer) {
							MmochatPet myPet = ((MmochatPlayer) role)
									.getPetInBattle();
							if (myPet == pet) {
								owner = (MmochatPlayer) role;
								break;
							}
						}
					}
				}
				if (owner == null) {
					continue;
				}
				MmochatPackageGrid grid = owner.getMyPackage().get(
						action.getGridId());
				if (grid == null || grid.getObject() == null) {
					frame.setErrMsg("此物品已用光!");
					break;
				}
				MmochatCommonObject prop = grid.getObject();
				if (prop.isUsedOut()) {
					frame.setErrMsg("此物品已用光!");
					break;
				}
				Byte ownerPos = battle.getPos(owner);
				frame.addTarget(action.getTargetPos(), true);
				int addBlood = 0, addSprit = 0;
				boolean isAddBlood = false, isAddSprit = false, isPkFunction = false;
				switch (prop.getObjectType()) {
				case 药品: {
					MmochatDrugType type = prop.getDrugType();
					addBlood = type.getBlood();
					addSprit = type.getSprit();
					if (addBlood > 0) {
						isAddBlood = true;
					}
					if (addSprit > 0) {
						isAddSprit = true;
					}
					prop.use(1);
					break;
				}
				case 道具: {
					// 战斗中使用道具单独处理
					if (prop.getCurPropAmount() > 0) {
						switch (prop.getPropType()) {
						case 大法玲珑:
						case 中法玲珑:
						case 小法玲珑: {
							isAddSprit = true;
							int spritNeed = 0;
							if (targetRole instanceof MmochatPlayer) {
								MmochatPlayer user = (MmochatPlayer) targetRole;
								spritNeed = user.getTotalSprit()
										- user.getCurPkSprit();
								if (spritNeed > 0) {
									spritNeed = Math.min(spritNeed,
											MmochatConstant.maxSpritPropCanAdd);
									spritNeed = Math.min(spritNeed, prop
											.getCurPropAmount());
									addSprit = spritNeed;
									prop.use(spritNeed);
								}
							} else if (targetRole instanceof MmochatPet) {
								MmochatPet pet = (MmochatPet) targetRole;
								spritNeed = 0;
								if (pet != null) {
									spritNeed = pet.getTotalSprit()
											- pet.getCurPkSprit();
									if (spritNeed > 0) {
										spritNeed = Math
												.min(
														spritNeed,
														MmochatConstant.maxSpritPropCanAdd);
										spritNeed = Math.min(spritNeed, prop
												.getCurPropAmount());
										addSprit = spritNeed;
										prop.use(spritNeed);
									}
								}
							}
							break;
						}
						case 大血玲珑:
						case 中血玲珑:
						case 小血玲珑:
						case 大血瓶:
						case 中血瓶:
						case 小血瓶: {
							isAddBlood = true;
							int bloodNeed = 0;
							if (targetRole instanceof MmochatPlayer) {
								MmochatPlayer user = (MmochatPlayer) targetRole;
								bloodNeed = user.getTotalBlood()
										- user.getCurPkBlood();
								if (bloodNeed > 0) {
									bloodNeed = Math
											.min(
													bloodNeed,
													MmochatConstant
															.getMaxBloodPropCanAdd(battle
																	.getType()));
									bloodNeed = Math.min(bloodNeed, prop
											.getCurPropAmount());
									addBlood = bloodNeed;
									prop.use(bloodNeed);
								}
							} else if (targetRole instanceof MmochatPet) {
								MmochatPet pet = (MmochatPet) targetRole;
								bloodNeed = 0;
								if (pet != null) {
									bloodNeed = pet.getTotalBlood()
											- pet.getCurPkBlood();
									if (bloodNeed > 0) {
										bloodNeed = Math
												.min(
														bloodNeed,
														MmochatConstant
																.getMaxBloodPropCanAdd(battle
																		.getType()));
										bloodNeed = Math.min(bloodNeed, prop
												.getCurPropAmount());
										addBlood = bloodNeed;
										prop.use(bloodNeed);
									}
								}
							}
							break;
						}
						case 三魂丹: {
							// 扣蓝
							isPkFunction = true;
							int costSprit = MmochatLifeSkillService
									.getCostSprit(prop);
							if (myRole instanceof MmochatPlayer
									|| myRole instanceof MmochatPet) {
								if (myRole.getCurPkSprit() < costSprit) {
									frame.setErrMsg("法力不足,无法使用使用三魂丹!");
									break;
								}
								myRole.delCurPkSprit(costSprit);
								frame.addNewRoleState_changeState(action
										.getPos(), myRole);
							}
							// 如果是首次使用，则开始计时
							if (prop.getStartTick() == null) {
								prop.setStartTick(System.currentTimeMillis());
							}
							int keepRound = MmochatLifeSkillService
									.getKeepRound(prop);
							int defendTimes = MmochatLifeSkillService
									.getDefendTimes(prop);
							double effectValue = MmochatLifeSkillService
									.getEffectValue(prop);
							MmochatSme newSme = new MmochatSme(
									MmochatSmeType.三魂丹);
							newSme.setKeepRound(keepRound);
							newSme.setDefendTimes(defendTimes);
							newSme.setValue(effectValue);
							if (prop.getPropLevel() != null) {
								newSme.setValue2(prop.getPropLevel());
							}

							Byte targetPos = battle.getPos(targetRole);
							targetRole.delSme(MmochatSmeType.七魄丹);
							targetRole.addSme(newSme);

							// 被障碍时不变身，防止障碍动画消失
							if (targetRole.hasSme(MmochatSmeType.封印)
									|| targetRole.hasSme(MmochatSmeType.冰冻)
									|| targetRole.hasSme(MmochatSmeType.混乱)) {
							} else {
								frame.addNewRoleState_delRole(targetPos,
										targetRole);
								frame.addNewRoleState_addRole(targetPos,
										targetRole, MmochatRoleBmpType.动物);
								targetRole
										.setCurRoleBmpType(MmochatRoleBmpType.动物);
							}
							break;
						}
						case 七魄丹: {
							// 扣蓝
							isPkFunction = true;
							int costSprit = MmochatLifeSkillService
									.getCostSprit(prop);
							if (myRole instanceof MmochatPlayer
									|| myRole instanceof MmochatPet) {
								if (myRole.getCurPkSprit() < costSprit) {
									frame.setErrMsg("法力不足,无法使用七魄丹!");
									break;
								}
								myRole.delCurPkSprit(costSprit);
								frame.addNewRoleState_changeState(action
										.getPos(), myRole);
							}
							// 如果是首次使用，则开始计时
							if (prop.getStartTick() == null) {
								prop.setStartTick(System.currentTimeMillis());
							}
							int keepRound = MmochatLifeSkillService
									.getKeepRound(prop);
							int defendTimes = MmochatLifeSkillService
									.getDefendTimes(prop);
							double effectValue = MmochatLifeSkillService
									.getEffectValue(prop);
							MmochatSme newSme = new MmochatSme(
									MmochatSmeType.七魄丹);
							newSme.setKeepRound(keepRound);
							newSme.setDefendTimes(defendTimes);
							newSme.setValue(effectValue);
							if (prop.getPropLevel() != null) {
								newSme.setValue2(prop.getPropLevel());
							}

							Byte targetPos = battle.getPos(targetRole);
							targetRole.delSme(MmochatSmeType.三魂丹);
							targetRole.addSme(newSme);

							// 被障碍时不变身，防止障碍动画消失
							if (targetRole.hasSme(MmochatSmeType.封印)
									|| targetRole.hasSme(MmochatSmeType.冰冻)
									|| targetRole.hasSme(MmochatSmeType.混乱)) {
							} else {
								frame.addNewRoleState_delRole(targetPos,
										targetRole);
								frame.addNewRoleState_addRole(targetPos,
										targetRole, MmochatRoleBmpType.小草);
								targetRole
										.setCurRoleBmpType(MmochatRoleBmpType.小草);
							}
							break;
						}
						case 妙手回春丹: {
							isPkFunction = true;

							// 扣蓝
							int costSprit = MmochatLifeSkillService
									.getCostSprit(prop);
							if (myRole instanceof MmochatPlayer
									|| myRole instanceof MmochatPet) {
								if (myRole.getCurPkSprit() < costSprit) {
									frame.setErrMsg("法力不足,无法使用妙手回春丹!");
									break;
								}
								myRole.delCurPkSprit(costSprit);
								frame.addNewRoleState_changeState(action
										.getPos(), myRole);
							}
							// 如果是首次使用，则开始计时
							if (prop.getStartTick() == null) {
								prop.setStartTick(System.currentTimeMillis());
							}
							int keepRound = MmochatLifeSkillService
									.getKeepRound(prop);
							double effectValue = MmochatLifeSkillService
									.getEffectValue(prop);
							MmochatSme newSme = new MmochatSme(
									MmochatSmeType.妙手回春丹);
							newSme.setKeepRound(keepRound);
							newSme.setValue(effectValue);
							if (prop.getPropLevel() != null) {
								newSme.setValue2(prop.getPropLevel());
							}

							Byte targetPos = battle.getPos(targetRole);
							targetRole.addSme(newSme);
							break;
						}
						case 魂魄归位丹: {
							isPkFunction = true;

							// 扣蓝
							int costSprit = MmochatLifeSkillService
									.getCostSprit(prop);
							if (myRole instanceof MmochatPlayer
									|| myRole instanceof MmochatPet) {
								if (myRole.getCurPkSprit() < costSprit) {
									frame.setErrMsg("法力不足,无法使用魂魄归位丹!");
									break;
								}
								myRole.delCurPkSprit(costSprit);
								frame.addNewRoleState_changeState(action
										.getPos(), myRole);
							}
							// 如果是首次使用，则开始计时
							if (prop.getStartTick() == null) {
								prop.setStartTick(System.currentTimeMillis());
							}
							MmochatSme newSme = new MmochatSme(
									MmochatSmeType.魂魄归位丹);
							newSme.setKeepRound(1000);
							if (prop.getPropLevel() != null) {
								newSme.setValue2(prop.getPropLevel());
							}
							Byte targetPos = battle.getPos(targetRole);
							targetRole.addSme(newSme);
							break;
						}
						default:
							break;
						}
					}
				}
					break;
				default:
					break;
				}
				if (isAddBlood || isAddSprit || isPkFunction) {
					// 加血加蓝或战斗中使用的道具
					if (prop.isUsedOut()) {
						grid.setObject(null);
					}
					if (targetRole.hasSme(MmochatSmeType.死亡)) {
						if (!targetRole.isCanRescure()) {
							break;
						}
					}
					Mmochat_5_1S pack = new Mmochat_5_1S();
					pack.addGrid(grid);
					MmochatUtil.sendCommonPack(owner, pack);

					targetRole.delCurPkBlood(-1 * addBlood);
					targetRole.delCurPkSprit(-1 * addSprit);
					if (targetRole.getCurPkBlood() > 0) {
						targetRole.delSme(MmochatSmeType.死亡);
					}
					frame.addNewRoleState_changeState(action.getTargetPos(),
							targetRole);
					if (isAddBlood) {
						frame.setActionType(MmochatActionType.加血);
					} else {
						frame.setActionType(MmochatActionType.加蓝);
					}
				} else {
					frame.setErrMsg("此物品无法在战斗中使用!");
					break;
				}
				break;
			}
			case 防御:
				myRole.setUseDefendInPk(true);
				break;
			case 保护:
				break;
			case 召唤: {
				if (myRole instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) myRole;
					MmochatPet pet = me.getPets().get((int) action.getGridId());
					MmochatPet pkPet = me.getPetInBattle();
					if (pkPet == pet || pet == null || pet.getCurPkBlood() <= 0
							|| pet.isHasUsedInPk()) {
						break;
					}

					if (pkPet != null) {
						// 从战场中清除
						if (pkPet.getCurPkBlood() > 0) {
							Byte targetPos = battle.getPos(pkPet);
							if (targetPos != null) {
								frame.addNewRoleState_delRole(targetPos, pkPet);
								battle.delRole(targetPos, false);
							}
						}
						pkPet.setHasUsedInPk(true);
						pkPet.setInPk(false);
					}
					MmochatPet p = me.getPkPet();
					if (p != null && p != pet) {
						p.setState(MmochatPetStateType.休息);
					}
					pet.setState(MmochatPetStateType.参战);
					pet.setInPk(true);
					pet.setHasUsedInPk(true);
					// 增加到战场中
					byte petPos = MmochatBattle.getPetPos(action.getPos());
					frame.addNewRoleState_addRole(petPos, pet);
					battle.addRole(petPos, pet);

					Mmochat_5_10S pack1 = new Mmochat_5_10S();
					pack1.setReset(true);
					pack1.setPets(new ArrayList<MmochatPet>(me.getPets()
							.values()));
					MmochatUtil.sendCommonPack(me, pack1);
				}
				break;
			}
			case 召回: {
				if (myRole instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) myRole;
					MmochatPet pet = me.getPetInBattle();
					if (pet != null && pet.getCurPkBlood() > 0) {
						pet.setHasUsedInPk(true);
						pet.setInPk(false);
						// 从战场中清除
						Byte targetPos = battle.getPos(pet);
						if (targetPos != null) {
							frame.addNewRoleState_delRole(targetPos, pet);
							battle.delRole(targetPos, false);
						}
					}
				}
				break;
			}
			case 捕捉: {
				MmochatRole targetRole = battle.getRoles().get(
						action.getTargetPos());
				if (targetRole == null) {
					frame.setErrMsg("目标不存在,捕捉失败!");
					break;
				}
				if (myRole instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) myRole;
					if ((targetRole instanceof MmochatPlayer)
							|| (targetRole instanceof MmochatPet)) {
						frame.setErrMsg("目标无法捕捉!");
						break;
					} else if (targetRole instanceof MmochatMonster) {
						// 怪物
						MmochatMonster monster = (MmochatMonster) targetRole;
						if (monster.getPetType() != MmochatPetType.野生) {
							frame.setErrMsg("目标无法捕捉!");
							break;
						} else if (!battle.getType().equals(
								MmochatBattleType.野外打怪)) {
							frame.setErrMsg("目标无法捕捉!");
							break;
						} else if (!monster.isCanBeCatch()) {
							frame.setErrMsg("目标无法捕捉!");
							break;
						} else {
							// TODO:其它情况下无法捕捉
							if (myRole.getLevel() < targetRole.getLevel()) {
								frame.setErrMsg("等级不够,捕捉失败!");
								break;
							} else if (me.isPetFull()) {
								frame.setErrMsg("您的宠物数量已达上限!");
								break;
							} else {
								// TODO:捕捉耗蓝,蓝不足提示
								int delta = myRole.getLevel()
										- targetRole.getLevel();
								int percent = Math.min(100, 60 + delta * 2);
								Byte targetPos = battle.getPos(targetRole);
								boolean hit = MmochatUtil.isInPercent(percent);
								frame.addTarget(targetPos, hit);
								if (hit) {
									// 捕捉成功
									// 如果血量为1点，则捉到的是宝宝
									// 如果血量为2点，则捉到的是药兽
									boolean isBaby = false;
									if (monster.getTotalBlood() == 1
											|| monster.getTotalBlood() == 2) {
										isBaby = true;
									}
									MmochatPet pet = MmochatPetService
											.createPetFromMonster(monster,
													isBaby);
									if (monster.getTotalBlood() == 2) {
										pet.setPetType(MmochatPetType.药兽);
									}
									if (pet != null) {
										pet.setCurPkBlood(pet.getTotalBlood());
										pet.setCurPkSprit(pet.getTotalSprit());
										me.addPet(pet);
										try {
											MmochatDao.updateRolePets(me);
										} catch (Exception e) {
											e.printStackTrace();
										}
										Mmochat_5_10S pack = new Mmochat_5_10S();
										pack.addPet(pet);
										MmochatUtil.sendCommonPack(me, pack);
									}
									// 从战场中删除目标
									frame.addNewRoleState_delRole(targetPos,
											targetRole);
									battle.delRole(targetPos, false);
								}
							}
						}
					}
				} else {
					frame.setErrMsg("您无法进行此操作!");
					break;
				}
				break;
			}
			case 逃跑: {
				// 判断是否逃跑成功
				if (battle.getType() == MmochatBattleType.跨服武道会比赛) {
					// 跨服武道会比赛中允许队长逃跑，并判定为输
					MmochatPlayer me = (MmochatPlayer) myRole;
					if (MmochatTeamService.getTeamState(me) == MmochatTeamStateType.队员) {
						frame.setErrMsg("此战斗只允许队长逃跑!");
						break;
					}

					// 积分处理
					Byte myPos = battle.getPos(myRole);
					battle.setWinTeam(battle.getTheOtherTeam(myPos));
					battle.setLoseTeam(battle.getMyTeam(myPos));
					battle.handleAward();

					// 下发让所有人退出战斗
					MmochatBattle endBattle = new MmochatBattle();
					endBattle.setBattleId(action.getBattleId());
					endBattle.setTurn(action.getTurn() + 1);
					endBattle.setOver();
					Mmochat_3_3S pack = new Mmochat_3_3S();
					pack.setBattle(endBattle);
					for (MmochatRole r : battle.getRoles().values()) {
						if (r instanceof MmochatPlayer) {
							MmochatPlayer he = (MmochatPlayer) r;
							MmochatUtil.sendCommonPack(he, pack);
						}
					}
					// 关闭战斗
					battle.closeBattle();

					frame.addTarget(action.getPos(), true);
					battle.addFrame(frame);
					return battle;
				} else if (battle.getType() == MmochatBattleType.强制杀戮) {
					// 强制杀戮中允许队长逃跑，并判定为输
					MmochatPlayer me = (MmochatPlayer) myRole;
					if (MmochatTeamService.getTeamState(me) == MmochatTeamStateType.队员) {
						frame.setErrMsg("此战斗只允许队长逃跑!");
						break;
					}

					// 积分处理
					Byte myPos = battle.getPos(myRole);
					battle.setWinTeam(battle.getTheOtherTeam(myPos));
					battle.setLoseTeam(battle.getMyTeam(myPos));
					battle.handleAward();

					// 下发让所有人退出战斗
					MmochatBattle endBattle = new MmochatBattle();
					endBattle.setBattleId(action.getBattleId());
					endBattle.setTurn(action.getTurn() + 1);
					endBattle.setOver();
					Mmochat_3_3S pack = new Mmochat_3_3S();
					pack.setBattle(endBattle);
					for (MmochatRole r : battle.getRoles().values()) {
						if (r instanceof MmochatPlayer) {
							MmochatPlayer he = (MmochatPlayer) r;
							MmochatUtil.sendCommonPack(he, pack);
						}
					}
					// 关闭战斗
					battle.closeBattle();

					frame.addTarget(action.getPos(), true);
					battle.addFrame(frame);
					return battle;
				} else {
					if (!battle.isCanEscape()) {
						frame.setErrMsg("此战斗不允许逃跑!");
						break;
					}
					boolean hit = MmochatUtil.isInPercent(80);
					frame.addTarget(action.getPos(), hit);
					Byte pos = battle.getPos(myRole);
					if (hit) {
						// 逃跑成功.自己离队,离开战斗,更新数据库,如果掉线则离开游戏
						MmochatBattle myBattle = battle.getClone();
						myBattle.addFrame(frame);
						myBattle.setOver();
						myBattle.addTurn();

						if (myRole instanceof MmochatPlayer) {
							MmochatPlayer me = (MmochatPlayer) myRole;
							if (me.isInTeam()) {
								MmochatTeam team = MmochatTeamService.teams
										.get(me.getTeamId());
								if (team == null) {
									me.leaveTeam();
								} else {
									team.leaveTeam(me.getRoleId());
								}
							}
							if (!me.isDeadConnection()) {
								SendBigPackUtil.sendBigPack_pkAction(me,
										myBattle, null);
							}
							me.leaveBattle();
							for (MmochatPet pet : me.getPets().values()) {
								pet.leaveBattle();
							}

							// 更新气血值，人宠头像信息等
							switch (myBattle.getType()) {
							case 友好切磋: {
								break;
							}
							case 比武场比武: {
								// 逃跑按输处理
								float loserPower = 0, winnerPower = 0;
								int winNum = 0, loseNum = 0;
								for (MmochatRole role : battle.getTheOtherTeam(
										pos).values()) {
									if (role instanceof MmochatPlayer) {
										MmochatPlayer me1 = (MmochatPlayer) role;
										winNum++;
										winnerPower += 1.0 * getRolePower(me1
												.getLevel(), me1.getLife_turn());
									}
								}
								for (MmochatRole role : battle.getMyTeam(pos)
										.values()) {
									if (role instanceof MmochatPlayer) {
										MmochatPlayer me1 = (MmochatPlayer) role;
										loseNum++;
										loserPower += 1.0 * getRolePower(me1
												.getLevel(), me1.getLife_turn());
									}
								}
								if (loserPower == 0 || winnerPower == 0) {
									break;
								}
								int totalLoseZhanji = 0;
								int minTeamNum = Math.min(winNum, loseNum);
								if (loserPower > winnerPower) {
									float param = loserPower / winnerPower;
									totalLoseZhanji = (int) (200 + 200 * (param - 1))
											* minTeamNum;
								} else {
									float param = winnerPower / loserPower;
									totalLoseZhanji = (int) (200 - 200 * (param - 1))
											* minTeamNum;
								}
								totalLoseZhanji = Math.max(10, totalLoseZhanji);
								totalLoseZhanji = Math.min(10000,
										totalLoseZhanji);
								int loseZhanjiPerRole = totalLoseZhanji
										/ Math.max(loseNum, 1);
								loseZhanjiPerRole *= 1.2;
								me.addZhanji(-1 * loseZhanjiPerRole);
								MmochatChatService.sendSystemMsgToPerson(me,
										"您逃跑了,损失" + loseZhanjiPerRole
												+ "点战绩(失败损失的1.2倍)!");
								break;
							}
							case 跨服擂台比武: {
								// 逃跑按输处理
								float loserPower = 0, winnerPower = 0;
								int winNum = 0, loseNum = 0;
								for (MmochatRole role : battle.getTheOtherTeam(
										pos).values()) {
									if (role instanceof MmochatPlayer) {
										MmochatPlayer me1 = (MmochatPlayer) role;
										winNum++;
										winnerPower += 1.0 * getRolePower(me1
												.getLevel(), me1.getLife_turn());
									}
								}
								for (MmochatRole role : battle.getMyTeam(pos)
										.values()) {
									if (role instanceof MmochatPlayer) {
										MmochatPlayer me1 = (MmochatPlayer) role;
										loseNum++;
										loserPower += 1.0 * getRolePower(me1
												.getLevel(), me1.getLife_turn());
									}
								}
								if (loserPower == 0 || winnerPower == 0) {
									break;
								}
								int totalLoseZhanji = 0;
								int minTeamNum = Math.min(winNum, loseNum);
								if (loserPower > winnerPower) {
									float param = loserPower / winnerPower;
									totalLoseZhanji = (int) (30 + 30 * (param - 1))
											* minTeamNum;
								} else {
									float param = winnerPower / loserPower;
									totalLoseZhanji = (int) (30 - 30 * (param - 1))
											* minTeamNum;
								}
								totalLoseZhanji = Math.max(10, totalLoseZhanji);
								totalLoseZhanji = Math.min(100 * minTeamNum,
										totalLoseZhanji);
								int loseZhanjiPerRole = totalLoseZhanji
										/ Math.max(loseNum, 1);
								loseZhanjiPerRole *= 1.2;
								me.addPk_score(-1 * loseZhanjiPerRole);
								MmochatChatService.sendSystemMsgToPerson(me,
										"您逃跑了，损失" + loseZhanjiPerRole
												+ "点竞技点(失败损失的1.2倍)!当前竞技点："
												+ me.getPk_score() + "点!");
								if (me.getPk_score() < MmochatConstant.minPkScoreNeed) {
									MmochatChatService
											.sendSystemMsgToPerson(
													me,
													"您的竞技点不足"
															+ MmochatConstant.minPkScoreNeed
															+ "点，无法继续比武，请退出!在原区服内在线每分钟将恢复5点竞技点!");
								}
								// 保存数据库
								MmochatMain.serverListDaoService.updatePkScore(
										me.getRoleId() % 10000000, me
												.getRegServerInstId(), me
												.getPk_score());

								// float loserPower = 0, winnerPower = 0;
								// int winNum = 0, loseNum = 0;
								// long totalPkScore = 0;
								// for (MmochatRole role :
								// battle.getTheOtherTeam(pos)
								// .values()) {
								// if (role instanceof MmochatPlayer) {
								// MmochatPlayer me1 = (MmochatPlayer) role;
								// winNum++;
								// winnerPower += me1.getPk_score()
								// * me1.getPk_score();
								// }
								// }
								// for (MmochatRole role : battle.getMyTeam(pos)
								// .values()) {
								// if (role instanceof MmochatPlayer) {
								// MmochatPlayer me1 = (MmochatPlayer) role;
								// loseNum++;
								// loserPower += me1.getPk_score()
								// * me1.getPk_score();
								// totalPkScore += me1.getPk_score();
								// }
								// }
								// loserPower = Math.max(1, loserPower);
								// winnerPower = Math.max(1, winnerPower);
								// totalPkScore = Math.max(1, totalPkScore);
								// int totalLoseZhanji = 0;
								// int minTeamNum = Math.min(winNum, loseNum);
								// if (loserPower > winnerPower) {
								// float param = loserPower / winnerPower;
								// totalLoseZhanji = (int) (30 + 15 * (param -
								// 1))
								// * minTeamNum;
								// } else {
								// float param = winnerPower / loserPower;
								// totalLoseZhanji = (int) (30 - 5 * (param -
								// 1))
								// * minTeamNum;
								// }
								// totalLoseZhanji = Math.max(1,
								// totalLoseZhanji);
								// totalLoseZhanji = Math.min(90 * minTeamNum,
								// totalLoseZhanji);
								//
								// int loseZhanjiPerRole = (int) (1.2 *
								// totalLoseZhanji
								// * me.getPk_score() / totalPkScore);
								// me.addPk_score(-1 * loseZhanjiPerRole);
								// MmochatChatService.sendSystemMsgToPerson(me,
								// "您逃跑了，损失" + loseZhanjiPerRole
								// + "点竞技点(失败损失的1.2倍)!当前竞技点：" + me.getPk_score()
								// + "点!");
								// if (me.getPk_score() <
								// MmochatConstant.minPkScoreNeed) {
								// MmochatChatService
								// .sendSystemMsgToPerson(
								// me,
								// "您的竞技点不足"
								// + MmochatConstant.minPkScoreNeed
								// + "点，无法继续比武，请退出!在原区服内在线每分钟将恢复5点竞技点!");
								// }
								// // 保存数据库
								// MmochatMain.serverListDaoService.updatePkScore(me
								// .getRoleId()%10000000,
								// me.getRegServerInstId(),
								// me
								// .getPk_score());
								break;
							}
							case 锁妖塔战斗: {
								// 逃跑则挑战结束
								me.setCurBlood(Math.max(1, me.getCurPkBlood()));
								me.setCurSprit(Math.max(0, me.getCurPkSprit()));

								for (MmochatPet pet1 : me.getPets().values()) {
									pet1.setCurBlood(Math.max(1, pet1
											.getCurPkBlood()));
									pet1.setCurSprit(Math.max(0, pet1
											.getCurPkSprit()));
								}

								MmochatTask task = me
										.getTaskByType(MmochatTaskType.挑战锁妖塔);
								if (task == null
										|| task.getTaskState() != MmochatTaskStateType.已接) {
									break;
								}
								synchronized (task) {
									if (task.getTaskState() == MmochatTaskStateType.已接) {
										task
												.setTaskState(MmochatTaskStateType.已完成);
									} else {
										break;
									}
								}
								// 结算奖励
								MmochatPet pet = me.getPkPet();
								String info = "您完成了锁妖塔"
										+ MmochatTowerService
												.getTowerLevelCount(task)
										+ "层的挑战,获得了";
								if (task.getTaskTag() == MmochatConstant.taskTag_挑战经验通天塔) {
									int expAward = MmochatTowerService
											.getExpAwardOfTower(task);
									me.addExp(expAward);
									info += MmochatUtil.wrapColor(expAward
											+ "点经验", Color.green)
											+ "，";
									if (pet != null) {
										int petExpAward = MmochatBattleService
												.getRealExp(expAward, me, pet);
										pet.addExp(me, petExpAward);
										info += "您的宠物"
												+ pet.getName()
												+ "获得了"
												+ MmochatUtil.wrapColor(
														petExpAward + "点经验",
														Color.green) + "，";
									}
								} else {
									int daoAward = MmochatTowerService
											.getDaoAwardOfTower(task);
									// 刷道比赛
									MmochatPropService.dealDaoActivity(me,
											daoAward);

									int trueDao = MmochatBattleService
											.getRealDao(me, daoAward);
									me.addDao(trueDao);
									info += MmochatUtil.wrapColor(trueDao
											+ "天道行(削减前" + daoAward + "天)",
											Color.green)
											+ "，";
									if (pet != null) {
										int petDao = MmochatBattleService
												.getRealDaoOfLevel(daoAward,
														me, pet);
										int truePetDao = MmochatBattleService
												.getRealDao(pet, petDao);
										pet.addDao(truePetDao);
										info += "您的宠物"
												+ pet.getName()
												+ "获得了"
												+ MmochatUtil.wrapColor(
														truePetDao + "点武学",
														Color.green) + "，";
									}
								}
								info += "今天的挑战已完成!";
								MmochatFriendService
										.sendSystemMsgToPersonByFriendMessage(
												me, info);
								// 称号判断与处理，NPC是否替换
								boolean ret = MmochatTowerService
										.dealTowerBest(me, task);
								if (ret) {
									int lifeTurn = (task.getTaskLevel()
											+ MmochatConstant.startTowerLevelReduce - 120) / 10;
									if (lifeTurn < 0) {
										lifeTurn = 0;
									}
									int pureLevel = task.getTaskLevel()
											+ MmochatConstant.startTowerLevelReduce
											- lifeTurn * 10;
									String levelInfo = "";
									if (lifeTurn > 0) {
										levelInfo += lifeTurn + "转";
									}
									levelInfo += pureLevel + "级";

									String bestInfo = MmochatUtil.wrapColor(me
											.getName(), Color.green)
											+ "完成了"
											+ MmochatUtil
													.wrapColor(
															MmochatTowerService
																	.getTowerLevelCount(task)
																	+ "层",
															Color.yellow)
											+ "的锁妖塔挑战，成为了"
											+ levelInfo
											+ "中挑战层数最多的强者!";
									MmochatChatService.sendSystemMsg(bestInfo);
								}
								// 存数据库
								try {
									MmochatDao.saveExpAndDao(me);
								} catch (Exception e) {
									e.printStackTrace();
								}
								MmochatTaskService.dealFinishingTask(me, task);
								break;
							}
							case 野外打怪:
							case 普通任务:
							case 每日大众任务:
							case 每日等级任务:
							case 除暴安良:
							case 斩妖除魔:
							case 修仙之路:
							case 击杀BOSS:
							case 击杀天干地支:
							case 击杀活动怪物:
								defalut: {
									me.setCurBlood(Math.max(1, me
											.getCurPkBlood()));
									me.setCurSprit(Math.max(0, me
											.getCurPkSprit()));

									for (MmochatPet pet : me.getPets().values()) {
										pet.setCurBlood(Math.max(1, pet
												.getCurPkBlood()));
										pet.setCurSprit(Math.max(0, pet
												.getCurPkSprit()));
									}

									// 道具:血池法池效果
									MmochatPropService
											.useAutoAddBloodSpritProp(me);

									// 更新头像图标信息
									if (!me.isDeadConnection()) {
										Mmochat_1_7S pack1 = new Mmochat_1_7S();
										pack1.setMe(me);
										MmochatUtil.sendCommonPack(me, pack1);
									}
									break;
								}
							}

							// 从其它人的战场中清除
							frame.addNewRoleState_delRole(pos, myRole);
							battle.delRole(pos, false);
							byte petPos = MmochatBattle.getPetPos(pos);
							MmochatRole petRole = battle.getRoles().get(petPos);
							if (petRole != null
									&& petRole instanceof MmochatPet) {
								frame.addNewRoleState_delRole(petPos, petRole);
								battle.delRole(petPos, false);
							}

							if (me.isDeadConnection()) {
								MmochatMainService.leaveGame(me);
							}
							// 保存数据库
							MmochatBattleService.saveSqlAfterBattle(me);
						}
						break;
					} else {
						break;
					}
				}
			}
			case 阐教一阶攻击技能:
			case 阐教二阶攻击技能:
			case 阐教三阶攻击技能:
			case 阐教四阶攻击技能:
			case 阐教五阶攻击技能:
			case 截教一阶攻击技能:
			case 截教二阶攻击技能:
			case 截教三阶攻击技能:
			case 截教四阶攻击技能:
			case 截教五阶攻击技能:
			case 人教一阶攻击技能:
			case 人教二阶攻击技能:
			case 人教三阶攻击技能:
			case 人教四阶攻击技能:
			case 人教五阶攻击技能: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法进行法术攻击!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法进行法术攻击!");
					break;
				}
				int targetNum = 1;
				MmochatSkillType skillType = MmochatSkillType.get(action
						.getActionType());
				MmochatSkill skill = myRole.getSkills().get(skillType);

				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}
				targetNum = skill.getTargetNum(myRole);
				int tureTargetNum = targetNum;
				// 武魂技能:法术目标增加
				if (myRole instanceof MmochatPlayer) {
					int addSkillNumPercent = myRole
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.法术目标增加);
					if (MmochatUtil.isInPercent(addSkillNumPercent)) {
						tureTargetNum++;
					}
				}

				List<MmochatRole> targetList = getTargetRoleListBySpeedNoFreezeBigWave(
						battle, action.getTargetPos(), tureTargetNum);
				if (targetList.size() == 0) {
					continue;
				}

				// 主目标伤害加强
				double bloodParam = 1.0;
				if (targetNum >= 2) {
					if (myRole instanceof MmochatPlayer) {
						MmochatPlayer me = (MmochatPlayer) myRole;
						MmochatSpecialSkill specialSkill = me
								.getSpecialSkill(MmochatSpecialSkillType.一击必杀);
						if (specialSkill != null
								&& specialSkill.getLevel() > 0
								&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
										.getEffectKey())) {
							if ((targetNum == 2 && specialSkill.getLevel() >= 1)
									|| (targetNum == 3 && specialSkill
											.getLevel() >= 1)
									|| (targetNum == 4 && specialSkill
											.getLevel() >= 2)
									|| (targetNum == 5 && specialSkill
											.getLevel() >= 3)) {
								// 伤害加强
								bloodParam = 1.0 + MmochatSpecialSkillType
										.getAttackParamOf一击必杀(specialSkill
												.getLevel(), specialSkill
												.getProficiency(), targetNum) / 100.0;
							}
						}
					}
				}
				// 主目标位置
				byte strengthTargetPos = 0;
				for (MmochatRole targetRole : targetList) {
					strengthTargetPos = battle.getPos(targetRole);
					if (strengthTargetPos == action.getTargetPos()) {
						break;
					}
				}

				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					if (targetPos == null) {
						continue;
					}
					boolean isFreeze = targetRole.hasSme(MmochatSmeType.冰冻);
					boolean hit;
					if (isFreeze) {
						hit = true;
					} else {
						hit = calHit(myRole, targetRole, 1);
					}
					frame.addTarget(targetPos, hit);
					if (hit) {
						double attackParam = 1;
						if (strengthTargetPos == targetPos) {
							attackParam = bloodParam;
						}
						int[] attackValues = calMagicHurt(myRole, targetRole,
								skill, attackParam);

						targetRole.delCurPkBlood(attackValues[0]);
						if (targetRole.getCurPkBlood() <= 0) {
							if (!targetRole.isDisappearWhenDie()) {
								MmochatSme sme = new MmochatSme(
										MmochatSmeType.死亡, 1000);
								targetRole.addSme(sme);
								if (attackValues[1] == 1) {
									// 重置形象
									frame = resetRole(frame, targetPos,
											targetRole);
								} else {
									frame.addNewRoleState_changeState(
											targetPos, targetRole);
								}
								if (!targetRole.isCanRescure()) {
									battle.delRole(targetPos, true);
								}
							} else {
								// 死后消失
								dealBattleRoleDie(battle, frame, targetPos,
										targetRole);
							}
						} else {
							if (attackValues[1] == 1) {
								// 重置形象
								frame = resetRole(frame, targetPos, targetRole);
							} else {
								frame.addNewRoleState_changeState(targetPos,
										targetRole);
							}
						}
					}
				}
				break;
			}
			case 阐教一阶限制技能:
			case 阐教二阶限制技能:
			case 阐教三阶限制技能:
			case 阐教四阶限制技能:
			case 阐教五阶限制技能: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法施放障碍技能!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法施放障碍技能!");
					break;
				}
				int targetNum = 1;
				MmochatSkillType skillType = MmochatSkillType.get(action
						.getActionType());
				MmochatSkill skill = myRole.getSkills().get(skillType);

				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}
				targetNum = skill.getTargetNum(myRole);

				// 道法无边技能
				if (targetNum >= 3) {
					if (myRole instanceof MmochatPlayer) {
						MmochatPlayer me = (MmochatPlayer) myRole;
						MmochatSpecialSkill specialSkill = me
								.getSpecialSkill(MmochatSpecialSkillType.道法无边);
						if (specialSkill != null
								&& specialSkill.getLevel() > 0
								&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
										.getEffectKey())) {
							if ((targetNum == 3 && specialSkill.getLevel() >= 1)
									|| (targetNum == 4 && specialSkill
											.getLevel() >= 2)
									|| (targetNum == 5 && specialSkill
											.getLevel() >= 3)) {
								// 障碍目标机率增加
								double skillRate = MmochatSpecialSkillType
										.getLimitRateOf道法无边(specialSkill
												.getLevel(), specialSkill
												.getProficiency());
								if (MmochatUtil.isInPercent(skillRate)) {
									targetNum++;
								}
							}
						}
					}
				}

				// 武魂技能:障碍目标增加
				if (myRole instanceof MmochatPlayer) {
					int addSkillNumPercent = myRole
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.障碍目标增加);
					if (MmochatUtil.isInPercent(addSkillNumPercent)) {
						targetNum++;
					}
				}

				List<MmochatRole> targetList = getTargetRoleListBySpeedNoFreezeNoWave(
						battle, action.getTargetPos(), targetNum);
				if (targetList.size() == 0) {
					continue;
				}

				MmochatRoundFrame newframe = new MmochatRoundFrame();
				int resetNum = 0;
				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					frame.addTarget(targetPos, true);
					if (targetRole.hasSme(MmochatSmeType.冰冻)) {
						// 冰冻后不能被封印
						continue;
					}
					// 限制技能是否成功，及成功的回合数计算
					int hitPercent = getLimitRate(myRole, targetRole, skill);
					// 封印覆盖非冰冻的其它限制效果
					boolean hit = MmochatUtil.isInPercent(hitPercent);
					if (hit) {
						int limitRounds = getLimitKeepRounds(myRole,
								targetRole, skill);
						targetRole.delSme(MmochatSmeType.混乱);
						targetRole.addSme(new MmochatSme(MmochatSmeType.封印,
								limitRounds));
						frame
								.addNewRoleState_changeState(targetPos,
										targetRole);

						// 丹药效果
						if (myRole.hasSme(MmochatSmeType.魂魄归位丹)) {
							MmochatSme sme = myRole.getSme().get(
									MmochatSmeType.魂魄归位丹);
							if (sme != null) {
								int myLevel = (int) sme.getValue2();
								if (targetRole.getSme() != null) {
									boolean needResetRole = false;
									// 三魂丹
									MmochatSme hisSme = targetRole.getSme()
											.get(MmochatSmeType.三魂丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.三魂丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 七魄丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.七魄丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.七魄丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 妙手回春丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.妙手回春丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.妙手回春丹);
										needResetRole = true;
									}

									if (needResetRole) {
										resetNum++;
									}
								}
							}
						}
					}
				}
				// 在使用技能前，对角色图片进行变更
				if (resetNum > 0) {
					newframe.setPos(action.getPos());
					newframe.setActionType(MmochatActionType.自动);
					newframe.setErrMsg(resetNum + "个对手被您解除丹药效果,归位丹效果结束");
					myRole.getSme().remove(MmochatSmeType.魂魄归位丹);
					battle.addFrame(newframe);
				}
				break;
			}
			case 截教一阶限制技能:
			case 截教二阶限制技能:
			case 截教三阶限制技能:
			case 截教四阶限制技能:
			case 截教五阶限制技能: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法施放障碍技能!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法施放障碍技能!");
					break;
				}
				int targetNum = 1;
				MmochatSkillType skillType = MmochatSkillType.get(action
						.getActionType());
				MmochatSkill skill = myRole.getSkills().get(skillType);

				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}
				targetNum = skill.getTargetNum(myRole);

				// 道法无边技能
				if (targetNum >= 3) {
					if (myRole instanceof MmochatPlayer) {
						MmochatPlayer me = (MmochatPlayer) myRole;
						MmochatSpecialSkill specialSkill = me
								.getSpecialSkill(MmochatSpecialSkillType.道法无边);
						if (specialSkill != null
								&& specialSkill.getLevel() > 0
								&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
										.getEffectKey())) {
							if ((targetNum == 3 && specialSkill.getLevel() >= 1)
									|| (targetNum == 4 && specialSkill
											.getLevel() >= 2)
									|| (targetNum == 5 && specialSkill
											.getLevel() >= 3)) {
								// 障碍目标机率增加
								double skillRate = MmochatSpecialSkillType
										.getLimitRateOf道法无边(specialSkill
												.getLevel(), specialSkill
												.getProficiency());
								if (MmochatUtil.isInPercent(skillRate)) {
									targetNum++;
								}
							}
						}
					}
				}

				// 武魂技能:障碍目标增加
				if (myRole instanceof MmochatPlayer) {
					int addSkillNumPercent = myRole
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.障碍目标增加);
					if (MmochatUtil.isInPercent(addSkillNumPercent)) {
						targetNum++;
					}
				}

				List<MmochatRole> targetList = getTargetRoleListBySpeedNoFreezeNoWave(
						battle, action.getTargetPos(), targetNum);
				if (targetList.size() == 0) {
					continue;
				}
				MmochatRoundFrame newframe = new MmochatRoundFrame();
				int resetNum = 0;
				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					frame.addTarget(targetPos, true);
					if (targetRole.hasSme(MmochatSmeType.冰冻)) {
						// 冰冻后不能被混乱
						continue;
					}
					// 限制技能是否成功，及成功的回合数计算
					int hitPercent = getLimitRate(myRole, targetRole, skill);
					// 混乱覆盖非冰冻的其它限制效果
					boolean hit = MmochatUtil.isInPercent(hitPercent);
					if (hit) {
						int limitRounds = getLimitKeepRounds(myRole,
								targetRole, skill);
						targetRole.delSme(MmochatSmeType.封印);
						targetRole.addSme(new MmochatSme(MmochatSmeType.混乱,
								limitRounds));
						frame
								.addNewRoleState_changeState(targetPos,
										targetRole);

						// 丹药效果
						if (myRole.hasSme(MmochatSmeType.魂魄归位丹)) {
							MmochatSme sme = myRole.getSme().get(
									MmochatSmeType.魂魄归位丹);
							if (sme != null) {
								int myLevel = (int) sme.getValue2();
								if (targetRole.getSme() != null) {
									boolean needResetRole = false;
									// 三魂丹
									MmochatSme hisSme = targetRole.getSme()
											.get(MmochatSmeType.三魂丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.三魂丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 七魄丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.七魄丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.七魄丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 妙手回春丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.妙手回春丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.妙手回春丹);
										needResetRole = true;
									}

									if (needResetRole) {
										resetNum++;
									}
								}
							}
						}
					}
				}
				// 在使用技能前，对角色图片进行变更
				if (resetNum > 0) {
					newframe.setPos(action.getPos());
					newframe.setActionType(MmochatActionType.自动);
					newframe.setErrMsg(resetNum + "个对手被您解除丹药效果,归位丹效果结束");
					myRole.getSme().remove(MmochatSmeType.魂魄归位丹);
					battle.addFrame(newframe);
				}
				break;
			}
			case 人教一阶限制技能:
			case 人教二阶限制技能:
			case 人教三阶限制技能:
			case 人教四阶限制技能:
			case 人教五阶限制技能: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法施放障碍技能!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法施放障碍技能!");
					break;
				}
				int targetNum = 1;
				MmochatSkillType skillType = MmochatSkillType.get(action
						.getActionType());
				MmochatSkill skill = myRole.getSkills().get(skillType);
				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}
				targetNum = skill.getTargetNum(myRole);

				// 道法无边技能
				if (targetNum >= 3) {
					if (myRole instanceof MmochatPlayer) {
						MmochatPlayer me = (MmochatPlayer) myRole;
						MmochatSpecialSkill specialSkill = me
								.getSpecialSkill(MmochatSpecialSkillType.道法无边);
						if (specialSkill != null
								&& specialSkill.getLevel() > 0
								&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
										.getEffectKey())) {
							if ((targetNum == 3 && specialSkill.getLevel() >= 1)
									|| (targetNum == 4 && specialSkill
											.getLevel() >= 2)
									|| (targetNum == 5 && specialSkill
											.getLevel() >= 3)) {
								// 障碍目标机率增加
								double skillRate = MmochatSpecialSkillType
										.getLimitRateOf道法无边(specialSkill
												.getLevel(), specialSkill
												.getProficiency());
								if (MmochatUtil.isInPercent(skillRate)) {
									targetNum++;
								}
							}
						}
					}
				}

				// 武魂技能:障碍目标增加
				if (myRole instanceof MmochatPlayer) {
					int addSkillNumPercent = myRole
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.障碍目标增加);
					if (MmochatUtil.isInPercent(addSkillNumPercent)) {
						targetNum++;
					}
				}

				List<MmochatRole> targetList = getTargetRoleListBySpeedNoWave(
						battle, action.getTargetPos(), targetNum);
				if (targetList.size() == 0) {
					continue;
				}
				MmochatRoundFrame newframe = new MmochatRoundFrame();
				int resetNum = 0;
				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					frame.addTarget(targetPos, true);
					// 限制技能是否成功，及成功的回合数计算
					int hitPercent = getLimitRate(myRole, targetRole, skill);
					boolean hit = MmochatUtil.isInPercent(hitPercent);
					if (hit) {
						int limitRounds = getLimitKeepRounds(myRole,
								targetRole, skill);
						targetRole.delSme(MmochatSmeType.封印);
						targetRole.delSme(MmochatSmeType.混乱);
						targetRole.addSme(new MmochatSme(MmochatSmeType.冰冻,
								limitRounds));
						frame
								.addNewRoleState_changeState(targetPos,
										targetRole);

						// 丹药效果
						if (myRole.hasSme(MmochatSmeType.魂魄归位丹)) {
							MmochatSme sme = myRole.getSme().get(
									MmochatSmeType.魂魄归位丹);
							if (sme != null) {
								int myLevel = (int) sme.getValue2();
								if (targetRole.getSme() != null) {
									boolean needResetRole = false;
									// 三魂丹
									MmochatSme hisSme = targetRole.getSme()
											.get(MmochatSmeType.三魂丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.三魂丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 七魄丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.七魄丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.七魄丹);
										newframe = resetRole(newframe,
												targetPos, targetRole);
										needResetRole = true;
									}
									// 妙手回春丹
									hisSme = targetRole.getSme().get(
											MmochatSmeType.妙手回春丹);
									if (hisSme != null
											&& myLevel >= hisSme.getValue2()) {
										// 清除并重置角色图片
										targetRole.getSme().remove(
												MmochatSmeType.妙手回春丹);
										needResetRole = true;
									}

									if (needResetRole) {
										resetNum++;
									}
								}
							}
						}
					}
				}
				// 在使用技能前，对角色图片进行变更
				if (resetNum > 0) {
					newframe.setPos(action.getPos());
					newframe.setActionType(MmochatActionType.自动);
					newframe.setErrMsg(resetNum + "个对手被您解除丹药效果,归位丹效果结束");
					myRole.getSme().remove(MmochatSmeType.魂魄归位丹);
					battle.addFrame(newframe);
				}
				break;
			}
			case 阐教一阶辅助技能:
			case 阐教二阶辅助技能:
			case 阐教三阶辅助技能:
			case 阐教四阶辅助技能:
			case 阐教五阶辅助技能:
			case 截教一阶辅助技能:
			case 截教二阶辅助技能:
			case 截教三阶辅助技能:
			case 截教四阶辅助技能:
			case 截教五阶辅助技能:
			case 人教一阶辅助技能:
			case 人教二阶辅助技能:
			case 人教三阶辅助技能:
			case 人教四阶辅助技能:
			case 人教五阶辅助技能: {
				int targetNum = 1;
				MmochatSkillType skillType = MmochatSkillType.get(action
						.getActionType());
				MmochatSkill skill = myRole.getSkills().get(skillType);
				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					// 怪物，默认目标为自己
					action.setTargetPos(action.getPos());
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(skillType.getMaxLevel());
					}
				}
				targetNum = skill.getTargetNum(myRole);

				// 武魂技能:辅助目标增加
				if (myRole instanceof MmochatPlayer) {
					int addSkillNumPercent = myRole
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.辅助目标增加);
					if (MmochatUtil.isInPercent(addSkillNumPercent)) {
						targetNum++;
					}
				}

				List<MmochatRole> targetList = null;
				switch (skillType.getSkillFamily()) {
				case 阐教:
				case 人教:
					targetList = getTargetRoleListBySpeedNoFreezeNoWave(battle,
							action.getTargetPos(), targetNum);
					break;
				case 截教:
					targetList = getTargetRoleListByAttack(battle, action
							.getTargetPos(), targetNum);
					break;
				default:
					break;
				}
				if (targetList == null || targetList.size() == 0) {
					continue;
				}

				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					frame.addTarget(targetPos, true);
					if (targetRole.hasSme(MmochatSmeType.冰冻)) {
						// 冰冻后不能加辅助
						continue;
					}
					int keepRound = skill.getKeepRound();// 持续回合数
					MmochatSme sme = new MmochatSme();
					sme.setKeepRound(keepRound);
					sme.setValue(skill.getEffectValue());
					switch (skillType.getSkillFamily()) {
					case 阐教:
						sme.setType(MmochatSmeType.加速辅助);
						break;
					case 人教:
						sme.setType(MmochatSmeType.加防辅助);
						break;
					case 截教:
						sme.setType(MmochatSmeType.加攻辅助);
						break;
					default:
						break;
					}
					targetRole.addSme(sme);
					frame.addNewRoleState_changeState(targetPos, targetRole);
				}
				break;
			}
			case 阐教秒6攻击技能:
			case 阐教秒7攻击技能:
			case 阐教秒8攻击技能:
			case 阐教秒9攻击技能:
			case 阐教秒10攻击技能:
			case 截教秒6攻击技能:
			case 截教秒7攻击技能:
			case 截教秒8攻击技能:
			case 截教秒9攻击技能:
			case 截教秒10攻击技能:
			case 人教秒6攻击技能:
			case 人教秒7攻击技能:
			case 人教秒8攻击技能:
			case 人教秒9攻击技能:
			case 人教秒10攻击技能: {
				if (myRole.hasBattleOrder(MmochatBattleOrderType.引怪)) {
					frame.setErrMsg("本回合处理<引怪>状态，无法进行法术攻击!");
					break;
				}
				if (myRole.hasBattleOrder(MmochatBattleOrderType.隐身)) {
					frame.setErrMsg("本回合处理<隐身>状态，无法进行法术攻击!");
					break;
				}

				int targetNum = 10;
				MmochatSkillType skillType;
				switch (action.getActionType()) {
				case 阐教秒6攻击技能:
					targetNum = 6;
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 阐教秒7攻击技能:
					targetNum = 7;
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 阐教秒8攻击技能:
					targetNum = 8;
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 阐教秒9攻击技能:
					targetNum = 9;
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 阐教秒10攻击技能:
					targetNum = 10;
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 截教秒6攻击技能:
					targetNum = 6;
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 截教秒7攻击技能:
					targetNum = 7;
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 截教秒8攻击技能:
					targetNum = 8;
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 截教秒9攻击技能:
					targetNum = 9;
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 截教秒10攻击技能:
					targetNum = 10;
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 人教秒6攻击技能:
					targetNum = 6;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				case 人教秒7攻击技能:
					targetNum = 7;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				case 人教秒8攻击技能:
					targetNum = 8;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				case 人教秒9攻击技能:
					targetNum = 9;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				case 人教秒10攻击技能:
					targetNum = 10;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				default:
					targetNum = 6;
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				}
				MmochatSkill skill = myRole.getSkills().get(skillType);
				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}

				List<MmochatRole> targetList = getTargetRoleListBySpeedNoFreezeBigWave(
						battle, action.getTargetPos(), targetNum);
				if (targetList.size() == 0) {
					continue;
				}

				// 主目标伤害加强
				double bloodParam = 1.0;
				if (targetNum >= 3) {
					if (myRole instanceof MmochatPlayer) {
						MmochatPlayer me = (MmochatPlayer) myRole;
						MmochatSpecialSkill specialSkill = me
								.getSpecialSkill(MmochatSpecialSkillType.一击必杀);
						if (specialSkill != null
								&& specialSkill.getLevel() > 0
								&& me.hasPropEffect(MmochatPropType.秘籍技能时间书
										.getEffectKey())) {
							if ((targetNum == 3 && specialSkill.getLevel() >= 1)
									|| (targetNum == 4 && specialSkill
											.getLevel() >= 2)
									|| (targetNum == 5 && specialSkill
											.getLevel() >= 3)) {
								// 伤害加强
								bloodParam = 1.0 + MmochatSpecialSkillType
										.getAttackParamOf一击必杀(specialSkill
												.getLevel(), specialSkill
												.getProficiency(), targetNum) / 100.0;
							}
						}
					}
				}
				// 主目标位置
				byte strengthTargetPos = 0;
				for (MmochatRole targetRole : targetList) {
					strengthTargetPos = battle.getPos(targetRole);
					if (strengthTargetPos == action.getTargetPos()) {
						break;
					}
				}

				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					if (targetPos == null) {
						continue;
					}
					boolean isFreeze = targetRole.hasSme(MmochatSmeType.冰冻);
					boolean hit;
					if (isFreeze) {
						hit = true;
					} else {
						hit = calHit(myRole, targetRole, 1);
					}
					frame.addTarget(targetPos, hit);
					if (hit) {
						double attackParam = 1;
						if (strengthTargetPos == targetPos) {
							attackParam = bloodParam;
						}
						int[] attackValues = calMagicHurt(myRole, targetRole,
								skill, attackParam);

						targetRole.delCurPkBlood(attackValues[0]);
						if (targetRole.getCurPkBlood() <= 0) {
							if (!targetRole.isDisappearWhenDie()) {
								MmochatSme sme = new MmochatSme(
										MmochatSmeType.死亡, 1000);
								targetRole.addSme(sme);
								if (attackValues[1] == 1) {
									// 重置形象
									frame = resetRole(frame, targetPos,
											targetRole);
								} else {
									frame.addNewRoleState_changeState(
											targetPos, targetRole);
								}
								if (!targetRole.isCanRescure()) {
									battle.delRole(targetPos, true);
								}
							} else {
								// 死后消失
								dealBattleRoleDie(battle, frame, targetPos,
										targetRole);
							}
						} else {
							if (attackValues[1] == 1) {
								// 重置形象
								frame = resetRole(frame, targetPos, targetRole);
							} else {
								frame.addNewRoleState_changeState(targetPos,
										targetRole);
							}
						}
					}
				}
				break;
			}
			case 神级五毒缠身:
			case 神级五雷轰顶:
			case 神级冥河黑水: {
				// 目标数10个，伤害100万
				int targetNum = 10;
				MmochatSkillType skillType;
				switch (action.getActionType()) {
				case 神级五毒缠身:
					skillType = MmochatSkillType.五毒缠身;
					frame.setActionType(MmochatActionType.截教五阶攻击技能);
					break;
				case 神级五雷轰顶:
					skillType = MmochatSkillType.五雷轰顶;
					frame.setActionType(MmochatActionType.阐教五阶攻击技能);
					break;
				case 神级冥河黑水:
				default:
					skillType = MmochatSkillType.冥河黑水;
					frame.setActionType(MmochatActionType.人教五阶攻击技能);
					break;
				}
				MmochatSkill skill = myRole.getSkills().get(skillType);

				if (myRole instanceof MmochatPlayer
						|| myRole instanceof MmochatPet) {
					if (skill == null) {
						frame.setErrMsg("您尚未学此技能!");
						break;
					}
					if (myRole.getCurPkSprit() < skill
							.getCostSprit(myRole instanceof MmochatPet)) {
						frame.setErrMsg("法力不足,施法失败!");
						break;
					}
					myRole.delCurPkSprit(skill
							.getCostSprit(myRole instanceof MmochatPet));
					frame.addNewRoleState_changeState(action.getPos(), myRole);
				} else if (myRole instanceof MmochatMonster) {
					if (skill == null) {
						// 增加技能
						skill = new MmochatSkill();
						skill.setType(skillType);
						skill.setLevel(1);
					}
				}
				List<MmochatRole> targetList = getTargetRoleListBySpeedNoFreezeBigWave(
						battle, action.getTargetPos(), targetNum);
				if (targetList.size() == 0) {
					continue;
				}

				for (MmochatRole targetRole : targetList) {
					Byte targetPos = battle.getPos(targetRole);
					boolean isFreeze = targetRole.hasSme(MmochatSmeType.冰冻);
					boolean hit;
					if (isFreeze) {
						hit = true;
					} else {
						hit = calHit(myRole, targetRole, 1);
					}
					frame.addTarget(targetPos, hit);
					if (hit) {
						int attackValue = 1000000;
						if (isFreeze) {
							attackValue = (int) (attackValue * MmochatConstant.freezeAttackParam);
							attackValue = Math.max(attackValue, 1);
						}
						if (targetRole
								.hasBattleOrder(MmochatBattleOrderType.隐身)) {
							attackValue = 1;
						}
						targetRole.delCurPkBlood(attackValue);
						if (targetRole.getCurPkBlood() <= 0) {
							if (!targetRole.isDisappearWhenDie()) {
								MmochatSme sme = new MmochatSme(
										MmochatSmeType.死亡, 1000);
								targetRole.addSme(sme);
								frame.addNewRoleState_changeState(targetPos,
										targetRole);
								if (!targetRole.isCanRescure()) {
									battle.delRole(targetPos, true);
								}
							} else {
								// 死后消失
								dealBattleRoleDie(battle, frame, targetPos,
										targetRole);
							}
						} else {
							frame.addNewRoleState_changeState(targetPos,
									targetRole);
						}
					}
				}
				break;
			}
			case 嗜血: {
				// 查找是否有玩家"引怪"
				List<MmochatRole> members = getEnermyWithBattleOrder(battle,
						action.getPos(), MmochatBattleOrderType.引怪);
				if (members.size() > 0) {
					// 有人引怪，物攻之
					int index = MmochatUtil.getRandomValue(members.size());
					MmochatRole mainTarget = members.get(index);
					Byte mainTargetPos = battle.getPos(mainTarget);
					if (mainTargetPos != null) {
						boolean isFreeze = mainTarget.hasSme(MmochatSmeType.冰冻);
						boolean hit;
						if (isFreeze) {
							hit = true;
						} else {
							hit = calHit(myRole, mainTarget, 0);
						}
						frame.setActionType(MmochatActionType.物攻);
						frame.addTarget(mainTargetPos, hit);
						if (hit) {
							int[] attackValues = calPhysicalHurt(myRole,
									mainTarget);
							mainTarget.delCurPkBlood(attackValues[0]);
							if (mainTarget.getCurPkBlood() <= 0) {
								if (!mainTarget.isDisappearWhenDie()) {
									MmochatSme sme = new MmochatSme(
											MmochatSmeType.死亡, 1000);
									mainTarget.addSme(sme);
									if (attackValues[1] == 1) {
										// 重置形象
										frame = resetRole(frame, mainTargetPos,
												mainTarget);
									} else {
										frame.addNewRoleState_changeState(
												mainTargetPos, mainTarget);
									}
									if (!mainTarget.isCanRescure()) {
										battle.delRole(mainTargetPos, true);
									}
								} else {
									// 死后消失
									dealBattleRoleDie(battle, frame,
											mainTargetPos, mainTarget);
								}
							} else {
								if (attackValues[1] == 1) {
									// 重置形象
									frame = resetRole(frame, mainTargetPos,
											mainTarget);
								} else {
									frame.addNewRoleState_changeState(
											mainTargetPos, mainTarget);
								}
							}
						}
					}
				} else {
					// 嗜血
					Byte targetPos = action.getPos();
					action.setTargetPos(targetPos);
					frame.setActionType(MmochatActionType.截教一阶辅助技能);
					frame.addTarget(targetPos, true);
					int keepRound = 3;// 持续回合数
					MmochatSme sme = new MmochatSme();
					sme.setKeepRound(keepRound);
					sme.setValue(400);// 增加4倍伤害
					sme.setType(MmochatSmeType.加攻辅助);
					myRole.addSme(sme);
					frame.addNewRoleState_changeState(targetPos, myRole);
				}
				break;
			}
			default:
				break;
			}
			battle.addFrame(frame);

			// 是否一方全灭
			if (battle.canBattleBeOver()) {
				battle.setOver();
				// 后面其它人的操作不再执行
				return battle;
			}
		}

		// TODO:每回合自动回血,或脱离限制技能等操作
		// 回合操作后状态改变的角色:roundEndNewStates
		for (Entry<Byte, MmochatRole> entry : battle.getRoles().entrySet()) {
			MmochatRole role = entry.getValue();
			Byte pos = entry.getKey();

			if (role instanceof MmochatPlayer) {
				// 人物
				if (role.hasSme(MmochatSmeType.死亡)) {
					// 人物复活技能,复活并且恢复20%气血
					int rebornPercent = role
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.人物复活);
					if (MmochatUtil.isInPercent(rebornPercent)) {
						role.delSme(MmochatSmeType.死亡);
						role
								.delCurPkBlood((int) (-1 * role.getTotalBlood() * MmochatConstant.bloodPercentForReborn));
						battle.addNewRoleState_changeState(pos, role);
					}
				} else {
					// 人物回血
					int skillPercent = role
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.人物回血);
					if (MmochatUtil.isInPercent(skillPercent)) {
						role
								.delCurPkBlood((int) (-1 * role.getTotalBlood() * MmochatConstant.addBloodPercentForPkSkill));
						battle.addNewRoleState_changeState(pos, role);
					}
					// 人物回蓝
					skillPercent = role
							.getCommonEquipAttributeValue(MmochatEquipAttributeType.人物回蓝);
					if (MmochatUtil.isInPercent(skillPercent)) {
						role
								.delCurPkSprit((int) (-1 * role.getTotalSprit() * MmochatConstant.addSpritPercentForPkSkill));
						battle.addNewRoleState_changeState(pos, role);
					}

					// 解除封印
					if (role.hasSme(MmochatSmeType.封印)) {
						skillPercent = role
								.getCommonEquipAttributeValue(MmochatEquipAttributeType.解除封印);
						if (MmochatUtil.isInPercent(skillPercent)) {
							role.delSme(MmochatSmeType.封印);
							battle.addNewRoleState_changeState(pos, role);
						}
					}

					// 解除冰冻
					if (role.hasSme(MmochatSmeType.冰冻)) {
						skillPercent = role
								.getCommonEquipAttributeValue(MmochatEquipAttributeType.解除冰冻);
						if (MmochatUtil.isInPercent(skillPercent)) {
							role.delSme(MmochatSmeType.冰冻);
							battle.addNewRoleState_changeState(pos, role);
						}
					}

					// 解除混乱
					if (role.hasSme(MmochatSmeType.混乱)) {
						skillPercent = role
								.getCommonEquipAttributeValue(MmochatEquipAttributeType.解除混乱);
						if (MmochatUtil.isInPercent(skillPercent)) {
							role.delSme(MmochatSmeType.混乱);
							battle.addNewRoleState_changeState(pos, role);
						}
					}

				}
			} else if (role instanceof MmochatPet) {
				// 宠物
				byte manPos = MmochatBattle.getManPos(pos);
				MmochatRole myRole = battle.getRoles().get(manPos);
				if (myRole != null && myRole instanceof MmochatPlayer) {
					if (!role.hasSme(MmochatSmeType.死亡)) {
						// 宠物回血
						int skillPercent = myRole
								.getCommonEquipAttributeValue(MmochatEquipAttributeType.宠物回血);
						if (MmochatUtil.isInPercent(skillPercent)) {
							role
									.delCurPkBlood((int) (-1
											* role.getTotalBlood() * MmochatConstant.addPetBloodPercentForPkSkill));
							battle.addNewRoleState_changeState(pos, role);
						}
						// 宠物回蓝
						skillPercent = myRole
								.getCommonEquipAttributeValue(MmochatEquipAttributeType.宠物回蓝);
						if (MmochatUtil.isInPercent(skillPercent)) {
							role
									.delCurPkSprit((int) (-1
											* role.getTotalSprit() * MmochatConstant.addPetSpritPercentForPkSkill));
							battle.addNewRoleState_changeState(pos, role);
						}
					}
				}
			}

			// 妙手回春丹效果
			if (role.hasSme(MmochatSmeType.妙手回春丹)) {
				MmochatSme sme = role.getSme().get(MmochatSmeType.妙手回春丹);
				if (sme != null && sme.getValue() > 0 && sme.getKeepRound() > 0) {
					int addBlood = (int) (sme.getValue() * role.getTotalBlood());
					sme.setValue(sme.getValue() / 2);
					role.delCurPkBlood(-1 * addBlood);
					if (role.hasSme(MmochatSmeType.死亡)) {
						role.delSme(MmochatSmeType.死亡);
						sme.setKeepRound(0);
					}
					battle.addNewRoleState_changeState(pos, role);
				}
			}
			MmochatSmeResult ret = role.decreaseSme();
			switch (ret) {
			case 变更状态: {
				battle.addNewRoleState_changeState(pos, role);
				break;
			}
			case 重设角色: {
				if (role.hasSme(MmochatSmeType.封印)
						|| role.hasSme(MmochatSmeType.冰冻)
						|| role.hasSme(MmochatSmeType.混乱)) {
					// 被障碍时不变身，防止障碍动画消失
				} else {
					battle.addNewRoleState_delRole(pos, role);
					battle.addNewRoleState_addRole(pos, role);
					role.resetCurRoleBmpType();
				}
				break;
			}
			case 重设角色及变更状态: {
				if (role.hasSme(MmochatSmeType.封印)
						|| role.hasSme(MmochatSmeType.冰冻)
						|| role.hasSme(MmochatSmeType.混乱)) {
					// 被障碍时不变身，防止障碍动画消失
					battle.addNewRoleState_changeState(pos, role);
				} else {
					battle.addNewRoleState_delRole(pos, role);
					battle.addNewRoleState_addRole(pos, role);
					role.resetCurRoleBmpType();
				}
				break;
			}
			default:
				break;
			}

			// 回合结束时障碍效果消失，有丹药效果，但没变身：需要变身
			if (!role.hasSme(MmochatSmeType.封印)
					&& !role.hasSme(MmochatSmeType.冰冻)
					&& !role.hasSme(MmochatSmeType.混乱)) {
				if (role.hasSme(MmochatSmeType.三魂丹)
						&& role.getCurRoleBmpType() != MmochatRoleBmpType.动物) {
					battle.addNewRoleState_delRole(pos, role);
					battle.addNewRoleState_addRole(pos, role,
							MmochatRoleBmpType.动物);
					role.setCurRoleBmpType(MmochatRoleBmpType.动物);
				} else if (role.hasSme(MmochatSmeType.七魄丹)
						&& role.getCurRoleBmpType() != MmochatRoleBmpType.小草) {
					battle.addNewRoleState_delRole(pos, role);
					battle.addNewRoleState_addRole(pos, role,
							MmochatRoleBmpType.小草);
					role.setCurRoleBmpType(MmochatRoleBmpType.小草);
				}
			}

			role.decreaseBattleOrder();
		}
		return battle;
	}

	// 生成怪物操作
	public static MmochatAction getMonsterAction(MmochatMonster monster,
			MmochatBattle battle) {
		if (monster == null || battle == null) {
			return null;
		}
		Byte myPos = battle.getPos(monster);
		if (myPos == null) {
			return null;
		}
		// 已经操作过了
		if (battle.getActions().get(myPos) != null) {
			return null;
		}
		MmochatAction action = new MmochatAction();
		action.setRole(monster);
		action.setPos(myPos);
		action.setBattleId(battle.getBattleId());
		action.setTurn((short) battle.getTurn());

		// 已经设定固定的战斗方式
		if (monster.getFixedActionType() != null) {
			action.setActionType(monster.getFixedActionType());
			monster.reSetFixedActionType();
			return action;
		}

		// 特殊技能
		if (monster.getAttackModeOfSpecialSkill() != null) {
			for (MmochatAttackModeOfSpecialSkill mode : monster
					.getAttackModeOfSpecialSkill()) {
				if (monster.getCurPkBlood() <= monster.getTotalBlood()
						* mode.getStartBloodPercent() / 100) {
					if (MmochatUtil.isInPercent(mode.getOpportunity())) {
						if (mode.getHint() != null) {
							// 通过战斗聊天下发系统提示消息
							sendSystemBattleMsg(battle, "当前第"
									+ MmochatUtil.wrapColor(battle.getTurn(),
											Color.green) + "回合:"
									+ mode.getHint());
						}
						if (mode.isNextRound()) {
							// 下个回合执行
							monster.setFixedActionType(mode.getActionType());
							// 本回合继续执行其它AI操作
						} else {
							// 当前回合执行
							action.setActionType(mode.getActionType());
							return action;
						}
						break;
					}
				}
			}
		}

		// 自己补血
		if (monster.getAttackMode_addBlood() != null) {
			MmochatAttackModeOfAddBlood mode = monster.getAttackMode_addBlood();
			if (MmochatUtil.isInPercent(mode.getAddBloodOpportunity())) {
				if (monster.getCurPkBlood() <= monster.getTotalBlood()
						* mode.getTriggerBloodPercent() / 100) {
					action.setActionType(MmochatActionType.NPC补血);
					action.setAddBlood(monster.getTotalBlood()
							* mode.getAddBloodPercent() / 100);
					action.setTargetPos(myPos);
					return action;
				}
			}
		}
		// 救助队友
		if (monster.getAttackMode_rescueTeamer() != null) {
			MmochatAttackModeOfRescueTeamer mode = monster
					.getAttackMode_rescueTeamer();
			if (MmochatUtil.isInPercent(mode.getRescueOpportunity())) {
				Map<Byte, MmochatRole> myDeadTeamers = battle
						.getCanReLiveDeadTeamers(myPos);
				if (myDeadTeamers.size() > 0) {
					List<MmochatRole> deadRoles = new ArrayList<MmochatRole>(
							myDeadTeamers.values());
					int index = (int) (Math.random() * deadRoles.size());
					MmochatRole target = deadRoles.get(index);
					Byte targetPos = battle.getPos(target);
					action.setTargetPos(targetPos);
					action.setActionType(MmochatActionType.NPC补血);
					action.setAddBlood(target.getTotalBlood()
							* mode.getBloodPercent() / 100);
					return action;
				}
			}
		}

		// 常规攻击
		if (monster.getAttackMode_normal() != null) {
			// TODO:如果增加了技能，法攻需要相应增加判断
			MmochatAttackModeOfNormal mode = monster.getAttackMode_normal();
			int percent = (int) (Math.random() * 100);
			MmochatActionType actionType = null;
			boolean isLimitSkill = false;
			if (percent < mode.getPhysicalAttackOpportunity()) {
				// 物攻
				actionType = MmochatActionType.物攻;
			} else if (percent < mode.getPhysicalAttackOpportunity()
					+ mode.getMagicAttackOppotunity()) {
				// 法攻
				if (monster.getBossMaxSkillTargetNum() <= 0) {
					// 未设置怪物最大攻击目标数，则根据怪物等级生成
					if (monster.getLevel() < MmochatConstant.monsterSkill1LevelNeed) {
						actionType = MmochatActionType.物攻;
					} else if (monster.getLevel() < MmochatConstant.monsterSkill2LevelNeed
							|| MmochatUtil.isInPercent(30)) {
						if (monster.getFamily() == MmochatFamilyType.人教) {
							actionType = MmochatActionType.人教一阶攻击技能;
						} else if (monster.getFamily() == MmochatFamilyType.截教) {
							actionType = MmochatActionType.截教一阶攻击技能;
						} else if (monster.getFamily() == MmochatFamilyType.阐教) {
							actionType = MmochatActionType.阐教一阶攻击技能;
						}
					} else {
						if (monster.getFamily() == MmochatFamilyType.人教) {
							actionType = MmochatActionType.人教二阶攻击技能;
						} else if (monster.getFamily() == MmochatFamilyType.截教) {
							actionType = MmochatActionType.截教二阶攻击技能;
						} else if (monster.getFamily() == MmochatFamilyType.阐教) {
							actionType = MmochatActionType.阐教二阶攻击技能;
						}
					}
				} else {
					// 设置了怪物最大攻击目标数
					if (monster.getFamily() == MmochatFamilyType.人教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.人教一阶攻击技能;
							break;
						case 2:
							actionType = MmochatActionType.人教二阶攻击技能;
							break;
						case 3:
							actionType = MmochatActionType.人教三阶攻击技能;
							break;
						case 4:
							actionType = MmochatActionType.人教四阶攻击技能;
							break;
						case 5:
							actionType = MmochatActionType.人教五阶攻击技能;
							break;
						case 6:
							actionType = MmochatActionType.人教秒6攻击技能;
							break;
						case 7:
							actionType = MmochatActionType.人教秒7攻击技能;
							break;
						case 8:
							actionType = MmochatActionType.人教秒8攻击技能;
							break;
						case 9:
							actionType = MmochatActionType.人教秒9攻击技能;
							break;
						case 10:
							actionType = MmochatActionType.人教秒10攻击技能;
							break;
						default:
							actionType = MmochatActionType.人教三阶攻击技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.截教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.截教一阶攻击技能;
							break;
						case 2:
							actionType = MmochatActionType.截教二阶攻击技能;
							break;
						case 3:
							actionType = MmochatActionType.截教三阶攻击技能;
							break;
						case 4:
							actionType = MmochatActionType.截教四阶攻击技能;
							break;
						case 5:
							actionType = MmochatActionType.截教五阶攻击技能;
							break;
						case 6:
							actionType = MmochatActionType.截教秒6攻击技能;
							break;
						case 7:
							actionType = MmochatActionType.截教秒7攻击技能;
							break;
						case 8:
							actionType = MmochatActionType.截教秒8攻击技能;
							break;
						case 9:
							actionType = MmochatActionType.截教秒9攻击技能;
							break;
						case 10:
							actionType = MmochatActionType.截教秒10攻击技能;
							break;
						default:
							actionType = MmochatActionType.截教三阶攻击技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.阐教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.阐教一阶攻击技能;
							break;
						case 2:
							actionType = MmochatActionType.阐教二阶攻击技能;
							break;
						case 3:
							actionType = MmochatActionType.阐教三阶攻击技能;
							break;
						case 4:
							actionType = MmochatActionType.阐教四阶攻击技能;
							break;
						case 5:
							actionType = MmochatActionType.阐教五阶攻击技能;
							break;
						case 6:
							actionType = MmochatActionType.阐教秒6攻击技能;
							break;
						case 7:
							actionType = MmochatActionType.阐教秒7攻击技能;
							break;
						case 8:
							actionType = MmochatActionType.阐教秒8攻击技能;
							break;
						case 9:
							actionType = MmochatActionType.阐教秒9攻击技能;
							break;
						case 10:
							actionType = MmochatActionType.阐教秒10攻击技能;
							break;
						default:
							actionType = MmochatActionType.阐教三阶攻击技能;
							break;
						}
					}
				}
			} else if (percent < mode.getPhysicalAttackOpportunity()
					+ mode.getMagicAttackOppotunity()
					+ mode.getFuZhuOppotunity()) {
				// 辅助技能,使用最强多体限制技能
				if (monster.getBossMaxSkillTargetNum() <= 0) {
					actionType = MmochatActionType.物攻;
				} else {
					if (monster.getFamily() == MmochatFamilyType.人教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.人教一阶辅助技能;
							break;
						case 2:
							actionType = MmochatActionType.人教二阶辅助技能;
							break;
						case 3:
							actionType = MmochatActionType.人教三阶辅助技能;
							break;
						case 4:
							actionType = MmochatActionType.人教四阶辅助技能;
							break;
						case 5:
							actionType = MmochatActionType.人教五阶辅助技能;
							break;
						default:
							actionType = MmochatActionType.人教五阶辅助技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.截教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.截教一阶辅助技能;
							break;
						case 2:
							actionType = MmochatActionType.截教二阶辅助技能;
							break;
						case 3:
							actionType = MmochatActionType.截教三阶辅助技能;
							break;
						case 4:
							actionType = MmochatActionType.截教四阶辅助技能;
							break;
						case 5:
							actionType = MmochatActionType.截教五阶辅助技能;
							break;
						default:
							actionType = MmochatActionType.截教五阶辅助技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.阐教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.阐教一阶辅助技能;
							break;
						case 2:
							actionType = MmochatActionType.阐教二阶辅助技能;
							break;
						case 3:
							actionType = MmochatActionType.阐教三阶辅助技能;
							break;
						case 4:
							actionType = MmochatActionType.阐教四阶辅助技能;
							break;
						case 5:
							actionType = MmochatActionType.阐教五阶辅助技能;
							break;
						default:
							actionType = MmochatActionType.阐教五阶辅助技能;
							break;
						}
					}
				}
			} else {
				// 限制技能,使用最强多体限制技能
				if (monster.getBossMaxSkillTargetNum() <= 0) {
					actionType = MmochatActionType.物攻;
				} else {
					isLimitSkill = true;
					if (monster.getFamily() == MmochatFamilyType.人教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.人教一阶限制技能;
							break;
						case 2:
							actionType = MmochatActionType.人教二阶限制技能;
							break;
						case 3:
							actionType = MmochatActionType.人教三阶限制技能;
							break;
						case 4:
							actionType = MmochatActionType.人教四阶限制技能;
							break;
						case 5:
							actionType = MmochatActionType.人教五阶限制技能;
							break;
						default:
							actionType = MmochatActionType.人教五阶限制技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.截教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.截教一阶限制技能;
							break;
						case 2:
							actionType = MmochatActionType.截教二阶限制技能;
							break;
						case 3:
							actionType = MmochatActionType.截教三阶限制技能;
							break;
						case 4:
							actionType = MmochatActionType.截教四阶限制技能;
							break;
						case 5:
							actionType = MmochatActionType.截教五阶限制技能;
							break;
						default:
							actionType = MmochatActionType.截教五阶限制技能;
							break;
						}
					} else if (monster.getFamily() == MmochatFamilyType.阐教) {
						switch (monster.getBossMaxSkillTargetNum()) {
						case 1:
							actionType = MmochatActionType.阐教一阶限制技能;
							break;
						case 2:
							actionType = MmochatActionType.阐教二阶限制技能;
							break;
						case 3:
							actionType = MmochatActionType.阐教三阶限制技能;
							break;
						case 4:
							actionType = MmochatActionType.阐教四阶限制技能;
							break;
						case 5:
							actionType = MmochatActionType.阐教五阶限制技能;
							break;
						default:
							actionType = MmochatActionType.阐教五阶限制技能;
							break;
						}
					}
				}
			}
			if (actionType == null) {
				isLimitSkill = false;
				actionType = MmochatActionType.物攻;
			}
			// if (actionType != MmochatActionType.物攻) {
			// // 使用法术或障碍技能，如果怪物尚无此技能，先给怪增加此技能
			// MmochatSkillType skillType = MmochatSkillType.get(actionType);
			// if (skillType != null) {
			// if (monster.getSkills().get(skillType) == null) {
			// MmochatSkill skill = new MmochatSkill();
			// skill.setType(skillType);
			// skill.setLevel(1);
			// monster.addNewSkill(skill);
			// }
			// }
			// }
			action.setActionType(actionType);
			Map<Byte, MmochatRole> theOtherTeam = battle.getTheOtherTeam(myPos);
			if (theOtherTeam != null && theOtherTeam.size() > 0) {
				List<MmochatRole> roles = new ArrayList<MmochatRole>(
						theOtherTeam.values());
				MmochatRole target = null;
				try {
					if (isLimitSkill) {
						// 如果是障碍技能，如果对方所有活着的目标都处于障碍状态，那么不再障碍，改为物攻
						// 否则随机选择未障碍的目标
						List<MmochatRole> unLimitTarget = new ArrayList<MmochatRole>();
						for (MmochatRole role : roles) {
							if (role.hasSme(MmochatSmeType.死亡)
									|| role.hasSme(MmochatSmeType.封印)
									|| role.hasSme(MmochatSmeType.混乱)
									|| role.hasSme(MmochatSmeType.冰冻)) {
								continue;
							}
							unLimitTarget.add(role);
						}
						if (unLimitTarget.size() > 0) {
							int index = MmochatUtil
									.getRandomValue(unLimitTarget.size());
							target = unLimitTarget.get(index);
						} else {
							actionType = MmochatActionType.物攻;
							action.setActionType(actionType);
						}

						unLimitTarget.clear();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				if (target == null) {
					int targetIndex = (int) (Math.random() * roles.size());
					target = roles.get(targetIndex);
				}
				Byte targetPos = battle.getPos(target);
				action.setTargetPos(targetPos);

				roles.clear();
			}
			return action;
		}
		return action;
	}

	// 退出观战
	@SkymobiService
	public void handleC_3_9(SkymobiHandler handler, Mmochat_3_9C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return;
		}
		if (req.getBattleId() >= 0) {
			MmochatBattle battle = battles.get(req.getBattleId());
			if (battle == null || battle.isOver()) {
				me.unLockState();
				me.leaveWatchingBattle();
				return;
			}
			List<MmochatPlayer> watchList = new ArrayList<MmochatPlayer>();
			if (me.isInTeam()) {
				MmochatTeam team1 = MmochatTeamService.teams
						.get(me.getTeamId());
				if (team1 == null) {
					me.leaveTeam();
					watchList.add(me);
				} else {
					if (team1.getTeamLeaderRoleId() == me.getRoleId()) {
						// 队长退出观战，则成员也退出
						for (Integer roleId : team1.getMemberId().values()) {
							MmochatPlayer member = MmochatMainService
									.getRoleFromBuffer(roleId);
							if (member != null) {
								watchList.add(member);
							}
						}
					} else {
						watchList.add(me);
					}
				}
			} else {
				watchList.add(me);
			}

			for (MmochatPlayer role : watchList) {
				if (role.getState() == MmochatRoleStateType.进入观战时) {
					battle.getAudiences().remove(role.getRoleId());
					role.unLockState();
					role.leaveWatchingBattle();
					if (role.getRoleId() != me.getRoleId()) {
						// 向其它成员下发终端退出战斗协议
						MmochatBattle endBattle = new MmochatBattle();
						endBattle.setBattleId(battle.getBattleId());
						endBattle
								.setTurn(MmochatConstant.maxRoundPerBattle + 1);
						endBattle.setOver();
						Mmochat_3_3S pack = new Mmochat_3_3S();
						pack.setBattle(endBattle);
						MmochatUtil.sendCommonPack(role, pack);
					}
				}
			}
		} else {
			// ID为负数，则为退出录像观看
			MmochatBattleRecordPlayer recordPlayer = battleRecordPlayers.get(me
					.getRoleId());
			if (recordPlayer != null) {
				battleRecordPlayers.remove(recordPlayer.getRoleId());
			}
		}

	}

	// 战斗中发布系统消息
	public static void sendSystemBattleMsg(MmochatBattle battle, String sysInfo) {
		if (battle == null) {
			// 战斗不存在
			return;
		}
		String msg = MmochatUtil.wrapIcon(MmochatConstant.BMP_CHAT_SYSTEMTAG)
				+ MmochatUtil.wrapColor(sysInfo, Color.yellow);

		Mmochat_3_5S pack = new Mmochat_3_5S();
		pack.setBattleId(battle.getBattleId());
		pack.setChat(msg);

		// 场景等
		for (MmochatRole member : battle.getRoles().values()) {
			if (member instanceof MmochatPlayer) {
				MmochatPlayer me = (MmochatPlayer) member;
				MmochatUtil.sendCommonPack(me, pack);
			}
		}

		// 向观战者下发
		for (MmochatPlayer p : battle.getAudiences().values()) {
			if (p.isDeadConnection()) {
				continue;
			}
			MmochatUtil.sendCommonPack(p, pack);
		}
		battle.setLastSystemMsgShowTick(System.currentTimeMillis());
	}

	// 战斗中发布系统消息
	public static void sendSystemBattleMsgToPerson(MmochatBattle battle,
			String sysInfo, int roleId) {
		if (battle == null) {
			// 战斗不存在
			return;
		}
		String msg = MmochatUtil.wrapIcon(MmochatConstant.BMP_CHAT_SYSTEMTAG)
				+ sysInfo;

		Mmochat_3_5S pack = new Mmochat_3_5S();
		pack.setBattleId(battle.getBattleId());
		pack.setChat(msg);

		// 场景等
		for (MmochatRole member : battle.getRoles().values()) {
			if (member instanceof MmochatPlayer) {
				if (member.getId() == roleId) {
					MmochatPlayer me = (MmochatPlayer) member;
					MmochatUtil.sendCommonPack(me, pack);
					break;
				}
			}
		}
	}

	// 战斗中聊天
	@SkymobiService
	public void handleC_3_5(SkymobiHandler handler, Mmochat_3_5C req) {

		MmochatBattle battle = battles.get(req.getBattleId());
		if (battle == null) {
			// 战斗不存在
			return;
		}

		MmochatRole role = battle.getRoles().get(req.getPos());
		if (role == null) {
			// 角色不存在
			return;
		}
		String userMsg = req.getChat();
		MmochatBattleOrderType battleOrderType = null;
		try {
			battleOrderType = MmochatBattleOrderType.valueOf(userMsg);
		} catch (Exception e) {
		}
		if (battleOrderType != null) {
			if (role instanceof MmochatPlayer) {
				MmochatPlayer me = (MmochatPlayer) role;
				MmochatMap curMap = MmochatMapService.maps.get(me.getMapId());
				if (curMap != null) {
					if (curMap.getBattleOrders().contains(battleOrderType)) {
						role.addBattleOrder(battleOrderType);
						MmochatPet pkPet = me.getPetInBattle();
						if (pkPet != null) {
							pkPet.addBattleOrder(battleOrderType);
						}
						if (battleOrderType.isPublicInfo()) {
							sendSystemBattleMsg(battle, MmochatUtil.wrapColor(
									me.getName(), Color.yellow)
									+ "设置了指令"
									+ MmochatUtil.wrapColor(battleOrderType
											.toString(), Color.green)
									+ "，"
									+ MmochatUtil.wrapColor("第"
											+ battle.getTurn() + "回合",
											Color.magenta) + "有效");
						} else {
							sendSystemBattleMsgToPerson(battle, "指令"
									+ MmochatUtil.wrapColor(battleOrderType
											.toString(), Color.green)
									+ "设置成功，"
									+ MmochatUtil.wrapColor("第"
											+ battle.getTurn() + "回合",
											Color.magenta) + "有效", role.getId());
						}
						return;
					}
				}
			}
		}

		if (userMsg.equals("录像")) {
			if (role instanceof MmochatPlayer) {
				MmochatPlayer me = (MmochatPlayer) role;
				if (me.isVip()) {
					MmochatBattleRecord record = tmpBattleRecords.get(battle
							.getBattleId());
					if (record != null) {
						if (me.getRecordBattleId() != record.getId()) {
							String msg = "刚刚的战斗已录制完成。您可以在世界聊天中发送"
									+ MmochatUtil.wrapColor("#录像#", Color.red)
									+ "，即可将此录像发布出去供所有人观看，"
									+ MmochatConstant.recordLifeTime
									+ "分钟内未发布则录像自动删除。"
									+ "您也可以在玩家系统的战斗录像中查看此录像!";
							MmochatFriendService
									.sendSystemMsgToPersonByFriendMessage(me,
											msg);
						}
						me.setRecordBattleId(record.getId());
						record.setSave(true);
						sendSystemBattleMsgToPerson(battle, "本场战斗已录像!", role
								.getId());
						return;
					}
				} else {
					sendSystemBattleMsgToPerson(battle, "您不是VIP会员，无法录像!", role
							.getId());
					return;
				}
			}
		}

		if (System.currentTimeMillis() - battle.getLastSystemMsgShowTick() < MmochatConstant.systemPkChatLockTime) {
			// 系统消息期间，不允许发普通玩家消息，但可以发战斗指令
			return;
		}

		// 发言中包含非法字符
		if (userMsg.contains("") || userMsg.contains("")
				|| userMsg.contains("") || userMsg.contains("")) {
			Mmochat_3_5S pack = new Mmochat_3_5S();
			pack.setBattleId(req.getBattleId());
			pack.setChat(MmochatUtil
					.wrapIcon(MmochatConstant.BMP_CHAT_SYSTEMTAG)
					+ "您的发言中包含不可见字符!");
			if (role instanceof MmochatPlayer) {
				MmochatPlayer me = (MmochatPlayer) role;
				MmochatUtil.sendCommonPack(me, pack);
			}
			return;
		}

		String msg = MmochatFilterService.getFilterString(userMsg);
		msg = role.getName() + ":" + msg;

		if (req.getChannel() == 0) {
			msg = MmochatUtil.wrapIcon(MmochatConstant.BMP_CHAT_CURTAG) + msg;
		} else if (req.getChannel() == 1) {
			msg = MmochatUtil.wrapIcon(MmochatConstant.BMP_CHAT_TEAMTAG) + msg;
		}

		Mmochat_3_5S pack = new Mmochat_3_5S();
		pack.setBattleId(req.getBattleId());
		pack.setChat(msg);

		if (req.getChannel() == 1) {
			// 队伍
			for (MmochatRole member : battle.getMyTeam(req.getPos()).values()) {
				if (member instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) member;
					MmochatUtil.sendCommonPack(me, pack);
				}
			}
		} else {
			// 场景等
			for (MmochatRole member : battle.getRoles().values()) {
				if (member instanceof MmochatPlayer) {
					MmochatPlayer me = (MmochatPlayer) member;
					MmochatUtil.sendCommonPack(me, pack);
				}
			}

			// 向观战者下发
			for (MmochatPlayer p : battle.getAudiences().values()) {
				if (p.isDeadConnection()) {
					continue;
				}
				MmochatUtil.sendCommonPack(p, pack);
			}
		}

		// 战斗录像
		try {
			MmochatBattleRecord record = tmpBattleRecords.get(battle
					.getBattleId());
			if (record != null) {
				MmochatBattleChatRecord chatRecord = new MmochatBattleChatRecord();
				chatRecord.setChat(msg);
				record.getChats().add(chatRecord);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 获取个人能力权值:个人能力值 = level * level * 全力野蛮天赋角色物伤(穿上相应装备)
	public static int getRolePower(int level, int life_turn) {
		int power = level * level;

		// 物伤 = [100 + 10*等级 + 15*力量*(1+野蛮*0.03) + 装备"伤害" + 装备"物伤"] * [1 +
		// 装备"物伤加成"/100.0]
		int gift = Math.min(level / 2, MmochatConstant
				.getMaxNumPerGift(life_turn));
		int attackPoint = level * 5;
		int equipAttack = MmochatEquipService.getEquipBaseAttrValue(
				MmochatEquipType.武器, level, MmochatEquipAttributeType.伤害);
		int pAttack = (int) (100 + 10 * level + 15 * attackPoint
				* (1 + gift * 0.03) + equipAttack);

		power *= pAttack;
		power = Math.max(1, power);
		return power;
	}

	// 3.15 找开刷道奖励宝箱
	@SkymobiService
	public SkymobiProtocolMessage handleC_3_15(SkymobiHandler handler,
			Mmochat_3_15C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return null;
		}
		List<MmochatExtraRandomAward> list = battleExtraAward.get(me
				.getRoleId());
		if (list == null || list.size() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "您当前没有奖励宝箱!");
		}
		MmochatExtraRandomAward hit = null;
		for (MmochatExtraRandomAward extra : list) {
			if (!extra.isSent() && extra.getId() == req.getAwardId()) {
				hit = extra;
				break;
			}
		}
		if (hit == null) {
			return MmochatUtil.msgbox(req.getHallState(), "您当前没有奖励宝箱!");
		}
		synchronized (hit) {
			if (hit.isSent()) {
				return MmochatUtil.msgbox(req.getHallState(), "您当前没有奖励宝箱!");
			}
			hit.setSent(true);
		}
		int param = MmochatUtil.getRandomValue(1, 10);
		int award = param * hit.getBaseAward();
		me.addDao(award);
		try {
			list.remove(hit);
			if (list.size() == 0) {
				battleExtraAward.remove(me.getRoleId());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		String msg = MmochatUtil.wrapColor("您打开宝箱，发现宝箱中藏着"
				+ MmochatUtil.wrapColor(param + "倍道行奖励", Color.green) + "，您获得了"
				+ MmochatUtil.wrapColor(award + "天道行(削减后)", Color.green) + "!",
				Color.magenta);
		return MmochatUtil.msgbox(req.getHallState(), msg);
	}
}
